事务与非事务更新同一实体的冲突场景及影响探究
事务与非事务并发操作同一实体的行为分析
问题场景
我有一个包含sum字段的实体,在事务内完成该实体的读取、sum字段更新及保存操作;同时应用另一处未在事务内对同一实体执行读取、更新并保存操作,想了解该场景下的实际执行结果。
理论事件顺序(实体A初始sum值为1)
Transaction:查询实体ANon-transaction:查询实体ATransaction:将实体A.sum加1(内存中值变为2)Non-transaction:将实体A.sum加1(内存中值变为2)Transaction:保存实体A(数据库中sum更新为2)Non-transaction:保存实体ATransaction:事务完成Non-transaction:操作完成
核心疑问:
- 事务对实体施加的锁是否会阻止或导致非事务的读写操作失败?
- 非事务更新是否会干扰事务更新,导致
sum值恢复为初始值?
实际行为分析
1. 锁的影响:不会阻止读操作,写操作会短暂阻塞
以常见关系型数据库(如MySQL InnoDB引擎)的默认可重复读隔离级别为例:
- 事务查询实体时,会施加共享锁(读锁),非事务的查询操作可以正常获取读锁并读取数据,不会被阻塞。
- 事务执行保存(更新)操作时,会将共享锁升级为排他锁(写锁),且该锁会持有到事务完成(步骤7)。因此非事务的步骤6保存操作会被阻塞,直到事务提交、锁释放后才能执行,不会直接失败。
2. 数据更新结果:出现更新丢失,不会恢复为初始值
最终数据库中实体A的sum值会是2,而非预期的3,属于典型的更新丢失场景:
- 事务和非事务都是基于初始值
1完成的内存修改(均得到2); - 事务先将
sum更新为2写入数据库,但未提交; - 非事务的更新操作等待锁释放后,将自身计算的
2再次写入数据库,覆盖了事务的结果; - 整个过程不会出现
sum恢复为初始值1的情况,两次更新都是向数据库写入2,最终结果为2。
内容的提问来源于stack exchange,提问作者Micro
相关产品推荐
相关产品推荐

