简体   繁体   中英

java mysql transaction deadlock

I have a scenario like this (semi-pseudocode)

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) { }
}

then I have to do the opposite in another program concurrently to transfer from the second bank to the first one, so how do I avoid deadlock in this situation?

Add FOR UPDATE on the end of any SELECTs in the transaction.

SELECT cash FROM bank_1 WHERE user = 1 FOR UPDATE;

This locks the row(s) mentioned there so that other connections will not mess with the row before this transaction is finished.

(There are cases where FOR UPDATE is not needed, but that's a longer discussion.)

Consider a pattern like:

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

Also having each bank in its own table make it harder to write queries. Consider a single table with a bank_id .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM