情境简述:
交易A开始...
同时,事务B开始...
交易A开始...
START TRANSACTION;
UPDATE table_name SET column_name=column_name+1 WHERE id = 1 LIMIT 1;
同时,事务B开始...
START TRANSACTION;
UPDATE table_name SET column_name=column_name+1 WHERE id = 2 LIMIT 1;
UPDATE table_name SET column_name=column_name-1 WHERE id = 1 LIMIT 1;
COMMIT;
目前,事务B正在等待事务A锁定的行1。
而事务A则继续执行...
UPDATE table_name SET column_name=column_name-1 WHERE id = 2 LIMIT 1;
COMMIT;
现在我们遇到了死锁,所以两个事务都在等待对方解锁他们想要更新的行 :'(
正如我在标题中提到的,我们如何在RDBMS事务中防止死锁?
我认为唯一的解决方法是回滚事务B并重新执行它。但是我们如何发现自己处于死锁状态,并立即摆脱它,以及如何保证我们不会陷入无限循环(例如,在非常繁重的Web应用程序中)。
如果需要,我正在使用MySQL。但欢迎为其他RDBMS提供任何解决方案,以帮助从Google来到这里的其他人 :)