选择更新锁定

Posted

技术标签:

【中文标题】选择更新锁定【英文标题】:Select for Update Lock 【发布时间】:2014-05-14 12:38:22 【问题描述】:

我想防止我的存储过程中的记录同时更新(通过多个会话)。

1.我正在对特定行使用 SELECT FOR UPDATE 语句,我想对其进行更新。 这将锁定记录。

    我现在更新这条记录,然后提交它。因此锁定被释放,现在该记录可供其他用户/会话使用。

但是,当我尝试运行该过程时,我发现正在同时更新,这意味着 SELECT FOR UPDATE 无法正常工作。

请提供一些建议。

示例代码如下:

IF THEN
// do something
ELSIF THEN
BEGIN

 SELECT HIGH_NBR INTO P_NBR FROM ROUTE
 WHERE LC_CD = <KL_LCD> AND ROUTE_NBR =  <KL_ROUTE_NBR> 
 FOR UPDATE OF HIGH_NBR ;

 UPDATE ROUTE SET HIGH_NBR = (HIGH_NBR + 1) 
 WHERE LC_CD = <KL_LCD> AND ROUTE_NBR =  <KL_ROUTE_NBR>;

COMMIT;

END;

END IF;

在多用户环境中,我观察到 SELECT FOR UPDATE 锁没有发生。

我刚刚使用两台不同的计算机(会话)测试了该场景。这是我所做的。

    从一台计算机,执行 SELECT FOR UPDATE 语句 -- 锁定一行。 从另一台计算机,对同一记录执行 UPDATE 语句。

    更新没有发生,更新语句的Sql执行没有完成,即使过了很长时间。

    如果我们为记录发出 SELECT FOR UPDATE,那么锁什么时候释放。

【问题讨论】:

请展示更完整的代码集。 更新了代码片段。 你是如何并行运行程序 2x 的?在调试器中? @OldProgrammer No .. 我在我们的 DEV 环境中部署了代码。如果有办法并行运行该过程,请告诉我。我正在使用 Sql Developer 来编写我的查询。 所以在 sql developer 调试器中单步执行 pl/sql 代码。我保证,如果您在选择之后设置断点,然后从另一个会话(例如 sqlplus)调用该过程,它应该会阻塞。您还可以查询 v$lock 视图以查看锁定操作。 Here 是一个很好的链接。 【参考方案1】:

首先,您需要在开始查询之前将自动提交设置为 false。 并检查您的代码是否正常工作,您可以使用两个带有循环屏障的 Java 踏板 您还应该在代码上添加时间戳以检查到达代码的时间。

【讨论】:

以上是关于选择更新锁定的主要内容,如果未能解决你的问题,请参考以下文章

选择以行限制锁定更新跳过

选择从 JPA 级别锁定的更新跳过

更新和选择后sql server中的锁定错误

为啥在选择的更新跳过锁定时,若有的几个会话可以看到行?

如何锁定windows不让别人上网?

关于更新事务的 PHP PDO 选择的说明