我有一个类似这样的场景(半伪代码)
con.setAutoCommit(false);
try {
SELECT cash FROM bank_1 WHERE user = 1;
long money = rs.getLong("cash")
... if money >= the amount we want then...
UPDATE bank_1 SET cash=cash-money WHERE user = 1;
UPDATE bank_2 SET cash=cash+money WHERE user = 2;
con.commit();
} catch(Exception e1) {
con.rollBack();
} finally {
con.setAutoCommit(true);
try { con.close(); } catch(Exception e) { }
}然后我不得不同时在另一个程序中做相反的事情,从第二个库转移到第一个库,那么在这种情况下我如何避免死锁呢?
发布于 2021-10-24 04:44:05
在事务中任何SELECTs的末尾添加FOR UPDATE。
SELECT cash FROM bank_1 WHERE user = 1 FOR UPDATE;这将锁定其中提到的行,以便在此事务完成之前,其他连接不会扰乱该行。
(有些情况下不需要FOR UPDATE,但这是一个更长的讨论。)
发布于 2021-10-23 03:53:04
考虑如下模式:
BEGIN
UPDATE bank_1 SET cash=cash - $money WHERE user = 1 AND cash >= $money
if rows affected > 0
UPDATE bank_2 SET cash=cash + $money WHERE user = 2
COMMIT
else
ROLLBACK此外,每个银行都在自己的表中,这使得编写查询变得更加困难。考虑具有bank_id的单个表。
https://stackoverflow.com/questions/69684200
复制相似问题