5

我的应用程序间歇性地陷入僵局。我的应用程序有 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);

Session 2:(其他业务逻辑)

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

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

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

4

1 回答 1

10

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

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

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

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

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

这是一个死锁。您必须在完成记录工作后完成事务才能将其释放给其他进程。

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

于 2013-10-11T18:02:19.910 回答