MySQL InnoDB如何应付死锁

  死锁是事务处理型数据库系统的一个经典问题,但是它们并不是很危险的,除非它们如此地频繁以至于你根本处理不了几个事务。当因死锁而产生了回滚时,你通常可以在你的应用程序中重新发出一个事务即可。
  
  InnoDB使用自动地行级锁定。你可能恰好在插入或删除单一一条记录时产生死锁。这是因为这些操作并不是真正“原子(原子)”级的:他们会自动地在锁定插入/删除行的索引记录(可能有几个)。
  
  
  可以通过下面所示的技巧来应付死锁或减少死锁的次数:,
  
  在MySQL祝辞=3.23.52和祝辞=4.0.3的版本中使用显示INNODB状态来确定引起最后一个死锁的原因。这可以帮助你调整你的应用程序来避免死锁只
  总是准备在因死锁而发生错误时重新发出一个事务。死锁并不危险。仅仅只需重试一遍只
  经常提交你的事务。小的事务有较少的碰撞可能只
  如果使用锁定读取选择……更新或…锁在分享模式,尽量使用较低的隔离级读承诺只
  以一个固定秩序(一个固定的顺序)访问你的表和记录。这样事务将形成一个较精细的队列,而避免死锁只
  为你的表添加合适的索引。那么你的查询只需要扫描较少的索引,因而设置较少的锁定。使用解释选择来确定MySQL为你的查询挑选的适当的索引只
  尽量少用锁定:如果可以通过一个选择在一个较老的数据快照中获得所需数据,就不要再添加子句用于更新或锁定共享模式。在这时使用读承诺隔离级是较好的主意,因为在同一个事务中的每个一致的阅读只读取它最先确定的数据快照只
  如果仍然没有什么补救效果,使用表级锁定连载你的事务(序列化事务):锁表t1, t2,…;(与表t1和t2在这里做些什么);打开表。表级锁定可以使你的事务形成精细的队列。注意锁表隐含地启动一个事务,就如同命令开始,打开表如同提交一样隐含地结束一个事务只
  连载事务(序列化事务)的另一个解决办法就是建立一个仅有一行记录的辅助“信号量(信号量)”表,每一个事务在访问其它表之前均更新这个记录。通过这种方式所有的事务将持续执行。注意同时InnoDB实时死锁检测算法也在工作着,因为这个持续锁定锁(序列化)是一个行锁定。在MySQL中对于表级锁定我们必须采取超时方式只
  
  
  死锁检测与回滚
  InnoDB会自动检测一个事务的死锁并回滚一个或多个事务来防止死锁。从你版开始,InnoDB将设法提取小的事务来进行回滚。一个事务的大小由它所插入(插入),更新(更新)和删除(删除)的数据行数决定。你之前,InnoDB总是回滚的事务锁请求是最后一个来构建一个僵局,也就是说,一个循环等待图的交易。
  
  InnoDB不能检测出由MySQL的锁表语句引起的死锁,或其它的表类型中的锁定所引起的死锁。你不得不通过中在my . cnf中所做设置innodb_lock_wait_timeout参数来解决这些情形。
  
  当InnoDB执行一个事务完整的回滚,这个事务所有所加的锁将被释放,然而,如果只一句的SQL语句因结果返回错误而进行回滚的,由这条SQL语句所设置的锁定可能会被保持。这是因为InnoDB r的行锁存储格式无法知道锁定是由哪个SQL语句所设置。
  
  
  
     

MySQL InnoDB如何应付死锁