为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 SELECT 会等待锁定?

为什么 SELECT 会等待锁定?

撒科打诨 2022-08-17 15:22:06
在我的应用程序中,我遇到了有时SELECT语句遇到异常的问题。可悲的是,我无法创建一个例子,因为情况非常复杂。所以问题只是关于一般理解。java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction一点背景信息:我正在使用具有READ_COMMITED隔离级别的MySQL(InnoDB)。实际上,我不明白SELECT如何通过该设置遇到锁定超时。我以为SELECT永远不会锁定,因为它只会返回最新的提交状态(由MySQL管理)。无论如何,根据正在发生的事情,这似乎是错误的。那么它到底是怎么回事呢?我已经读过这个 https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html 但这并没有真正给我一个线索。没有或类似的东西被使用。SELECT ... FOR UPDATE
查看完整描述

2 回答

?
慕妹3146593

TA贡献1820条经验 获得超9个赞

这可能是由于您的数据库。通常,这种问题来自该侧,而不是来自访问它的编程端。根据我对db的经验,这些问题通常是由于这一点。最后,编程方面只是“在那个数据库里为我得到那个”的事情。

我毫不费力地找到了这个

它基本上解释了:

Lock wait timeout通常发生在事务正在等待数据行更新时,该数据行已被其他事务锁定。

您还应该检查这个具有特定事务问题的答案,这可能会对您有所帮助,因为尝试更改不同的表可能会超时

查询试图更改一个或多个InnoDB表中的至少一行。由于您知道查询,因此所有被访问的表都是罪魁祸首的候选项。


查看完整回答
反对 回复 2022-08-17
?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

为了加快数据库中的查询速度,可以同时执行多个事务。例如,如果有人对公司员工的工资表运行选择查询(每个员工由id标识),而另一个更改了例如已婚人士的姓氏,则可以同时执行这两个查询,因为它们不会干扰。

但在其他情况下,即使是 SELECT 语句也可能会干扰另一个语句。

为了防止SQL事务中的意外结果,事务遵循ACID模型,该模型代表原子性,一致性,隔离性和持久性(有关更多信息,请阅读维基百科)。

假设事务 1 开始计算某些内容,然后想要将结果写入表 A。在编写之前,它会将所有 SELECT 语句锁定到表 A。否则,这会干扰隔离要求。因为如果事务 2 在 1 仍在写入时启动,则 2 的结果取决于 1 已写入的位置和未写入的位置。

现在,它甚至可能产生死锁。例如,在事务 1 可以写入表 A 中的最后一个字段之前,它仍然必须向表 B 写入一些内容,但事务 2 已经阻止了表 B 在从 A 读取后安全地读取表 B,现在你有一个死锁。2 想要从被 1 阻止的 A 读取,因此它等待 1 完成,但 1 等待 2 解锁表 B 自行完成。

为了解决这个问题,一种策略是在某个超时后回滚某些事务。(更多这里)

因此,这可能是您的 select 语句的读取,以获得超过锁定等待超时。

但是死锁通常只是巧合发生的,所以如果事务 2 被迫回滚,事务 1 应该能够完成,以便 2 应该能够在以后的尝试中成功。


查看完整回答
反对 回复 2022-08-17
  • 2 回答
  • 0 关注
  • 318 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号