What is the recommended way to handle double-spending issues in MySQL? Say, for example, I have an application that transfers $x
from account A
to B
like so:
- Start a transaction
- Ensures account
A
hasbalance >= $x
- Add
$x
toB
's balance - Deduct
$x
fromA
's balance - Commit (or rollback if a query failed)
I'm considering the scenario where two identical transactions are executed concurrently to transfer $x
from A
to B
. As long as A
's balance is at least $x
, the check in step #2 will pass for each transaction, as neither has updated the balance yet. This would allow an attacker to issue two transactions for the entirety of A
's balance and have them both executed, therefore enabling him to spend double the account's balance.
What is the recommended way to combat this? Would setting the MySQL isolation level to REPEATABLE_READ
suffice to protect against this? Alternatively I could ensure the query that deducts from A's balance includes a WHERE balance > $x
clause, and then rollback the transaction if there were zero rows affected. However, I'd ideally like to have this handled by the DBMS layer itself.
Thanks!