SELECT FOR UPDATE中的数据库死锁

时间:2013-10-11 17:51:21

标签: sql sql-update database-deadlocks

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

第1节:

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完成执行。

1 个答案:

答案 0 :(得分:5)

  

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

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

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

因此,进程1正在等待记录ID = 1并保持记录ID = 2

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

这是一个死锁。您必须在完成记录工作后完成交易,以便将其用于其他流程。

如果您需要在一个事务中更新多条记录,请将它们全部锁定在一起并在工作结束后免费。