SELECT FOR UPDATE 中的数据库死锁

2024-03-28

我的应用程序间歇性陷入僵局。我的应用程序有 1 个表,例如 EMPLOYEE(ID(PK)、NAME、SAL),并且有 2 个会话。

第一节:

SELECT ID, NAME, SAL FROM EMPLOYEE WHERE SAL = (SELECT MIN(SAL) FROM 
EMPLOYEE) FOR UPDATE
Let say the query return EMPLOYEE ROW having ID=2
then application does some processing like rs.updateInt(ID_SAL, 10);

会话2:(用于其他业务逻辑)

SELECT ID, NAME, SAL FROM EMPLOYEE WHERE ID=2 FOR UPDATE.

因此,在应用程序中,两个会话都尝试更新同一行(在 ID=2 的示例行中)这种情况是预料之中的,因此我认为 SELECT .. FOR UPDATE 会有所帮助。

难道我做错了什么?我假设 SELECT FOR UPDATE 将锁定该行,并且当其他会话尝试更新同一行时,它将等到会话 1 完成执行。


我假设 SELECT FOR UPDATE 将锁定该行,并且当其他会话尝试更新同一行时,它将等到会话 1 完成执行。

正是如此。但是,当您完成此行或关闭会话时,您需要关闭事务。 您的问题可能的情况如下:

进程 1 锁定 ID=2 的行,更新它并转到 ID=1 的下一条记录(但会话和事务仍然处于活动状态) 进程 2 已经锁定 ID=1 的行并将锁定 ID=2 的行(但会话和事务仍然处于活动状态)

所以进程1正在等待记录ID=1并保留记录ID=2

进程2正在等待记录ID=2并保留记录ID=1

这是一个死锁。您必须在完成记录工作后完成事务,以将其释放以供其他流程使用。

如果您需要在一个事务中更新多条记录,只需将它们全部锁定在一起并在工作完成后释放即可。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SELECT FOR UPDATE 中的数据库死锁 的相关文章

随机推荐