You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关系型数据库转账场景下的隔离级别与锁机制疑问

转账场景下Read Committed隔离级别与悲观锁的疑问解答

场景说明

假设有一张account表,结构如下:

account
id | balance

转账操作的示例代码为:

START TRANSACTION;
UPDATE account SET balance = balance - 100 WHERE id = 1;
UPDATE account SET balance = balance + 100 WHERE id = 2;
COMMIT;

应用中可能并行发起账户1转账户2与账户2转账户1的请求,针对该场景的隔离级别与锁机制疑问解答如下:


核心结论

Read Committed隔离级别足以保障该转账场景正常运行,且不需要额外使用悲观锁,原因如下:

1. Read Committed隔离级别的自动保障

Read Committed的核心规则是事务仅能读取已提交的数据,且数据库会为写操作自动添加行级排他锁(以InnoDB为例):

  • 当两个转账事务并行执行时,事务A(1转2)会先给id=1的行加排他锁,事务B(2转1)会先给id=2的行加排他锁;
  • 后续事务A尝试更新id=2的行时,会因该行被事务B锁定而进入等待;事务B尝试更新id=1的行时,也会因该行被事务A锁定进入等待;
  • 数据库的死锁检测机制会自动识别这种循环等待,回滚其中一个事务,另一个事务即可完成全部更新并提交,最终数据状态一致。

同时,你的转账逻辑中仅包含更新操作,没有读取操作,因此不存在脏读的触发条件——脏读是指读取到其他未提交事务的修改数据,而更新操作本身是基于已提交的数据状态(或等待锁释放后的最新状态)执行的,完全符合Read Committed的约束。

2. 无需额外添加悲观锁

数据库的更新语句本身会自动获取行级排他锁,效果与手动添加SELECT ... FOR UPDATE这类悲观锁完全一致,额外添加悲观锁反而可能增加死锁概率或不必要的性能开销。


会不会出现保障被违反的情况?

不会。在该场景下,Read Committed隔离级别结合数据库内置的行锁机制,已经完全覆盖了并发转账的冲突处理,不存在数据不一致或隔离性被破坏的情况。

内容的提问来源于stack exchange,提问作者Tipok

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 13:10:35