在存储过程中使用:
insert into aaa select * from bb ,cc,等,假设要往aa里面插入,需要查询关联8张表,这时候mysql 要锁住9张表,
这时候如果其他事务要对8张表里面的某些表进行修改等操作,非常容易产生死锁。不知道大家有没有碰到这情况,如果要用,通过什么方式用好点,避免产生死锁。可以换用游标,不知道还有没有其他方式?

解决方案 »

  1.   

    使用INNODB引擎,这样就不会锁表了,而是直接锁记录。
      

  2.   

    就是用INNODB 引擎的,是行几锁
      

  3.   

    使用INNODB 就是因为它支持事务,在并发高的系统里面,insert select 要锁住8张表,行级锁,,其他事务可能对8张表的某行记录进行修改,这样极度容易导成死锁。
      

  4.   


    对于“insert  into target_tab select * from source_tab where ...”和“create  table new_tab ...select ... From  source_tab where ...(CTAS)”这种SQL语句,用户并没有对source_tab做任何更新操作,但MySQL对这种SQL语句做了特别处理。设置系统变量innodb_locks_unsafe_for_binlog的值为“on”后,InnoDB不再对source_tab加锁.这样会造成Replication同步数据不一致问题.因此,INSERT...SELECT...和 CREATE TABLE...SELECT...语句,可能会阻止对源表的并发更新,造成对源表锁的等待。如果查询比较复杂的话,会造成严重的性能问题,我们在应用中应尽量避免使用。实际上,MySQL将这种SQL叫作不确定(non-deterministic)的SQL,不推荐使用。如果应用中一定要用这种SQL来实现业务逻辑,又不希望对源表的并发更新产生影响,可以采取以下两种措施:¡  一是采取上面示例中的做法,将innodb_locks_unsafe_for_binlog的值设置为“on”,强制MySQL使用多版本数据一致性读。但付出的代价是可能无法用binlog正确地恢复或复制数据,因此,不推荐使用这种方式。¡  二是通过使用“select * from source_tab ... Into outfile”和“load data infile ...”语句组合来间接实现,采用这种方式MySQL不会给source_tab加锁。