Multithreading 如何防止选择和更新之间的竞争条件
我正在做一个分类账模块。在这个过程中,我必须按顺序完成这些任务Multithreading 如何防止选择和更新之间的竞争条件,multithreading,postgresql,jdbc,locking,Multithreading,Postgresql,Jdbc,Locking,我正在做一个分类账模块。在这个过程中,我必须按顺序完成这些任务 从来源选择余额(表1第1行) 从目的地选择余额(表1第2行) 用一些逻辑修改平衡 更新来源的余额(表1第1行) 更新目的地的余额(表1第2行) 提交更改 将事务插入到事务表中 在多线程环境中,线程在前一个线程更新和提交之前获得平衡。 在Postgres中,在线程提交之前,对正在访问的行施加锁。在这种情况下,我看到了一个幻觉 尝试对整个模式使用同步块。没有帮助。 无法使用“从更新中选择”,因为更改余额的逻辑取决于其他操作 以下是一些日
[DEBUG] [2016-12-15 10:49:53,893] [1] - Src Ledger_book_idLB001
[DEBUG] [2016-12-15 10:49:53,893] [1] - Src Balance2500.0
[DEBUG] [2016-12-15 10:49:53,897] [1] - Dest Ledger_book_idLB002
[DEBUG] [2016-12-15 10:49:53,897] [1] - Dest Balance0.0
[DEBUG] [2016-12-15 10:49:53,898] [15] - Src Ledger_book_idLB001
[DEBUG] [2016-12-15 10:49:53,898] [15] - Src Balance2500.0
[DEBUG] [2016-12-15 10:49:53,899] [16] - Src Ledger_book_idLB001
[DEBUG] [2016-12-15 10:49:53,899] [16] - Src Balance2500.0
[DEBUG] [2016-12-15 10:49:53,900] [16] - Dest Ledger_book_idLB002
[DEBUG] [2016-12-15 10:49:53,900] [15] - Dest Ledger_book_idLB002
感谢您的帮助:)如果您对情况有任何疑问,请发表意见。
当子SELECT中出现锁定子句时,锁定的行是子查询返回到外部查询的行。这可能比单独检查子查询所建议的行少,因为外部查询的条件可能用于优化子查询的执行
所以你可以这样做
您还应该阅读CTE的页面,尤其是
您可以使用
serializable
隔离级别。如果您正在更新源代码
,是什么使它成为源代码
?来源和目的地的区别是什么?@EvanCarroll所说的来源我指的是来源账户。。。我正在尝试借记源中的金额,贷记目标中的金额。无法使用“从更新中选择”您的意思是SELECT。。。是否要更新
?很难理解您的日志,但我认为您的问题在于目标行的更改(其他行将被更新,而不是所选的行),对吗?是的,它是select。。。从更新
。我希望日志中的线程[15]和[16]等到[1]完成更新和提交。你可以在日志中看到它。请参考预期订单并与日志进行比较。感谢您的回复:)
WITH s1 AS (
SELECT balance FROM source
FOR UPDATE
), s2 AS (
SELECT balance destination
FOR UPDATE
), u1 AS (
UPDATE source SET balance = ...
WHERE... -- potential join to S2 if you need destination
RETURNING -- whatever you need (if anything)
), u2 AS (
UPDATE source SET balance = ...
WHERE... -- potential join to S1 if you need source
RETURNING -- whatever you need (if anything)
)
INSERT INTO transactions (foo,date) VALUES (bar,now());