我正在研究分类帐模块。在那个过程中,我必须按顺序执行这些任务
在多线程环境中,线程在上一次线程更新和提交之前获得平衡。 在Postgres中,对线程进行锁定,直到线程提交为止。在这种情况下,我看到了一个傻瓜。
尝试使用synchronized块作为整个模式。没有帮助。 不能使用SELECT FROM UPDATE,因为更改余额的逻辑取决于其他操作。
以下是一些日志,在[1]线程进入更新部分之前,其他线程收集现有余额。
[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
任何帮助表示赞赏:)请评论是否有任何关于这种情况的具体疑问。
答案 0 :(得分:0)
当锁定子句出现在子SELECT中时,锁定的行是子查询返回到外部查询的行。这可能涉及的行数少于单独检查子查询所表明的行数,因为来自外部查询的条件可能用于优化子查询的执行。
所以你可以这样做......
您还应该阅读有关CTE的页面,尤其是DATA-MODIFYING
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());