事物一
START TRANSACTION; UPDATE User SET age=18 WHERE id=3; UPDATE User SET age=20 WHERE id=4; COMMIT;
事物二
START TRANSACTION; UPDATE User SET age=18 WHERE id=4; UPDATE User SET age=20 WHERE id=3; COMMIT;
在多个请求并发访问时,两个事务都执行了第一条UPDATE语句,更新了一行数据,同时也锁定了该行数据,接着每个事务都尝试去执行第二条UPDATE语句,却发现该行已经被对方锁定,然后两个事务都在等待对方释放锁,同时又持有对方需要的锁,则陷入死循环,这就是死锁。
避免死锁:
1,业务逻辑上避免上述这种情况
2,死锁导致InnoDB回滚整个事务。若单是发生了lock wait timeout则InnoDB仅会回滚事务中等待锁并发生超时的SQL语句。若想在此种情况下回滚整个事务,可通过同时开启 --innodb_rollback_on_timeout选项。
3,尽可能在较少的记录上持有锁,并且锁定的时间尽可能的短
4,若非必要则不使用锁定读,若要选择使用锁定读则可选择较低的事务隔离级别如 READ COMMITTED。
5,select...into outfile和load data infile替换insert...select