根据How to Cope with Deadlocks的解释:
InnoDB uses automatic row-level locking. You can get deadlocks even in the case of transactions that just insert or delete a single row. That is because these operations are not really “atomic”; they automatically set locks on the (possibly several) index records of the row inserted or deleted.
以前在数据库领域积累的经验:为了避免数据死锁,尽量按照一致的顺序修改多张表。在此,该经验似乎无法奏效。当前MetaSeeker服务器的并发访问量很高,很容易观察到仅仅修改一条记录就引发死锁的情形。为了应对死锁,主要采用三个措施:
- Java应用层并发控制,对一些没有必要并发的情形使用适当的synchronized操作符进行控制
- 如Working around MySQL error “Deadlock found when trying to get lock; try restarting transaction”所述,用try...catch检测死锁,如果发生,则重新提交
- 为特殊情形准备一张作为信号灯(semaphore,信号量)的表,每个事务开头先修改该表,实际上,将事务顺序化了。
下面是监视死锁的Java代码片断
} catch (SQLException e) { String sqlState = e.getSQLState(); if ("40001".equals(sqlState)) { .... } }