我有两个线程,都需要更新同一行 .
该行看起来像:
-
(id,firstName,lastName)
-
(1,"xxxx",null)
-
1是主键值
更新看起来像:
Update table set lastName = "yyy" where id = 1 and lastName = null;
我想要的是如果一个线程成功地将null lastName更新为新值,我希望第二个线程失败并将某种异常返回给调用者 . 我需要一种方法来在更新期间知道该列不再为null(这意味着它已由第一个线程更新)
哪个更新声明将解决我的问题? ( select for update
, coalesce
等)
3 回答
您可以在默认的读提交隔离中使用它 .
对于exp:
但是如果你想在更新零行时引发错误,那么你应该使用可重复的读隔离 . 对于exp:
或者你使用函数来更新,并引发错误 . 对于exp:
SQL查询本身很好,只需将其包装在可序列化的事务中:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
在此隔离级别中,您可能会通过中止或重试事务来选择要处理的应用程序代码中的错误 .
更多信息:
http://wiki.postgresql.org/wiki/SSI
http://www.postgresql.org/docs/current/static/transaction-iso.html
隔离级别
这可以通过default isolation level READ COMMITTED中的常规
UPDATE
命令来完成 . 所有这些对于并发使用是安全的 .你可以使用
TRANSACTION ISOLATION LEVEL SERIALIZABLE
. 这将自动生成序列化失败异常 . 但这使得整个交易变得更加昂贵 . 而是在默认隔离级别中使用以下方法之一:命令错误
您的原始命令有两个错误:
值用单引号括起来,而不是双引号:
'yyy'
.something = NULL
始终是NULL
. 请改用something IS NULL
. Details in the manual.命令标记
它会告诉您受影响的行数:
实际上只有第一个
UPDATE
才能更新该行 . 以下所有尝试都不执行任何操作并返回UPDATE 0
.RETURNING子句
UPDATE
可以直接返回行:只有第一个
UPDATE
返回一个值 . 以下所有都不返回任何行 .PL / pgSQL函数引发异常
如果您确实需要例外: