A 给 B 转账的同时 B 给 A 转账,怎样避免死锁,又不让余额扣成负数?
先自己想一想,再看参考要点
参考要点
- 按账户 ID 从小到大加锁,两个方向的转账都先锁 id 小的行,就不会互相等待(实验中每 480 笔的死锁从约 70~100 次降为 0),只有涉及同一账户的转账在这一行的锁上排队,不是串行化
- 余额判断写在条件中:UPDATE account SET balance = balance - 100 WHERE id = 1 AND balance >= 100,影响 0 行说明余额不足、回滚,先读出余额在应用中算好再写回会互相覆盖
- 客户端生成的请求号作主键,死锁回滚或超时重试也只成功一次
- 每次变动写流水,用期初余额加流水合计核对当前余额