死锁是指两个或多个事务在同一资源上互相占用,并请求加锁时,而导致的恶性循环现象。当多个事务以不同顺序试图加锁同一资源时,就会产生死锁。任何时间,多个事务同时加锁同一资源,一定产生死锁。例如,设想下列两个事务同时处理StockPrice表:
如果凑巧,每个事务在处理过程中,都执行了第一个查询,更新了数据行,也加锁了该数据行。接着,每个事务都去试图更新第二个数据行,却发现该行已被(对方)加锁,然后两个事务都开始互相等待对方完成,陷入等待中,除非外部因素介入,才能解除死锁。
为了解决这个问题,数据库系统实现了各种死锁检测和死锁超时机制。对于更复杂的系统,InnoDB存储引擎,可以预知循环相关性,并立刻返回错误。这种解决方式实际很有效,否则死锁导致很慢的查询。其他的解决方式,是让查询达到一个锁等待超时时间,然后再放弃争用,但这种方法不够好。目前InnoDB处理死锁的方法是,回滚拥有最少排他行级锁的事务。
锁现象和锁顺序是因存储引擎而异的,某些存储引擎可能会因为使用某种顺序的语句导致死锁,其他的却不会。死锁现象具有双重性:有些是因真实的数据冲突产生的,无法避免,在些则是因为存储引擎的工作方式导致的。
如果不以部分或全部的方式回滚某个事务,死锁将无法解除。在事务性的系统中,这是个无法更改的事实。