15 条回复  ·  441 次点击
kele1997 小成 2024-7-13 00:00:34
@leejinhong mysql 有默认提交的话,每一行 sql 都是有事务保证原子性吧

而且默认 mysql 隔离级别不就是可重复读嘛,不就保证了一个事务多次读获得同一个值
vishun 小成 2024-7-13 11:50:14
总结下:
- 数据库层面:
  - 要么 field=field+xxx 来保证原子性,比较简单,但是无法阻止超发等场景。
  - fersion 乐观锁,大概率不会重复的情况下用。
  - select for update 悲观锁,经常重复的情况下用或不太在乎性能下用。
  - 极端的隔离级别设置为序列化,额,貌似很少用。
- 应用方面
  - 各种应用锁、redis 锁,分布式锁等。
mbeoliero123 初学 2024-7-13 12:04:08
行 sql 更新是会加行锁吧?这里并发冲突主要是你的 where 能不能找到原来的记录,如果是 where id = xxx ,这种并发度再高也是对那条记录进行串行操作,如果是 where fersion = xxx ,fersion 随时会变这种,感觉就是 4 楼说的乐观锁处理
wenxueywx 初学 2024-7-15 09:42:42
乐观锁策略(读多写少场景):
- 查询库存值
- 更新库存时带上之前查询的库存数据:update xxx set stock = stock-1 where id = xxx and stock = xx;
- 更新成功才记流水;更新失败就重试
悲观锁策略(写多读少场景):
- 查询库存时就加锁,select * from xxx where xxx for update;
- update
- 记流水
louettagfh 小成 2024-7-16 13:32:11
举个例子,在仓库库存管理中,如果在查询时库存是 30 ,但在查询完成后,其他业务操作改变了库存,导致库存变为 25 。然而,业务处理时依旧基于查询时的库存 30 进行操作,这样就会导致记录流水的值出现误差。

你这个例子就不可能在 MySQL 中发生.  一个事务不结束, 其他无法事务修改这个 record.
asmile1993 小成 2024-7-19 15:57:47
@leejinhong 如果只是简单的 select ,在 RR 隔离级别下看到的的确是事务开始时的值,但当对记录进行修改操作时,用的是当前读—读最新的已提交记录,而不是一开始 select 得到的结果,想要了解更深的话,搜索下快照读和当前读。
12
返回顶部