因为不同锁之间的兼容性关系,在有些时刻一个事务中的锁需要等待另一个事务中的锁释放它所占用的资源,这就是阻塞。阻塞并不是一件坏事,其是为了确保事务可以并发且正常地运行。
在 InnoDB存储引擎中,参数innodb_lock_wait_timeout用来控制等待的时间(默认是50秒), innodb_rollback_on_timeout用来设定是否在等待超时时对进行中的事务进行回滚操作(默认是OFF,代表不回滚)。参数innodb_lock_wait_timeout是动态的,可以在 MySQL数据库运行时进行调整
mysql> set innodb_lock_wait timeout=60;
Query OK, 0 rows affected (0.00 sec)
而innodb_rollback_on_timeout是静态的,不可在启动时进行修改。
当发生超时, MySQL数据库会抛出一个1205的错误,如:
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT FROM t WHERE a=1 FOR UPDATE;
ERROR 1205(HY000): Lock wait timeout exceeded; try restarting transaction
需要牢记的是,在默认情况下 InnoDB存储引擎不会回滚超时引发的错误异常。其实 InnoDB存储引擎在大部分情况下都不会对异常进行回滚。如在一个会话中执行了如下语句:
在会话A中开启了一个事务,在 Next-Key Lock算法下锁定了小于4的所有记录(其实也锁定了4这个记录本身)。在另一个会话B中执行如下语句:
可以看到,在会话B中插入记录5是可以的,但是在插入记录3时,因为会话A中Next-Key Lock算法的关系,需要等待会话A中事务释放这个资源,所以等待后产生了超时。但是在超时后用户再进行 SELECT操作时会发现,5这个记录依然存在。
这是因为这时会话B中的事务虽然抛出了异常,但是既没有进行COMMIT操作,也没有进行 ROLLBACK。而这是十分危险的状态,因此用户必须判断是否需要COMMIT还是 ROLLBACK,之后再进行下一步的操作。
Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。
它的内容包括:
- 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
- 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
- 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
- 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
- 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
- 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
- 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
- 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw
目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:
想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询
同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。