十一、MySQL 事务问题

  所谓“事务”,一般具有四个属性:原子性、一致性、隔离性、持久性。即一个事务是不可分割的工作单元,一个事务内的操作要么全部成功、要么全部失败。

事务问题

  对于一个单线程事务,如果成功就提交,如果失败则回滚。可是 MySQL 的事务是多线程并发的,对于缓存页中的一行数据,可能有多个事务在对其进行修改、查询,那么这时并发的修改、查询必然是有冲突的,会导致一些问题的出现。

脏写

  意思就是说有两个事务 A、B 同时在修改一条数据。

  当事务 A 修改了原始值 null 为值 A 后尚未提交事务。

  事务 B 修改了事务 A 刚才修改的值 A 为值 B 并提交。

  这时事务 A  回滚,把事务 B 修改的值 B 回滚为原始值,导致对于事务 B 而言,事务提交成功,但是值还是原始值 null。

  两个事务同时修改一条数据,一个事务回滚导致前一个事务提交的数据丢失,这就是所谓的脏写。

脏读

  两个事务 A、B 并发对一条数据进行读写操作。

  事务 A 对原始数据 null 修改为值 A 尚未提交时,事务 B 读取事务 A 刚才修改的值 A 返回并进行业务操作。

  此时事务 A 回滚,导致值 A 回滚为 null。对于事务 B 而言,他拿到的是事务 A 尚未提交事务的值 A,而实际上原始值并没有修改。

  一个事务读取到一个事务修改后尚未提交的值,就会导致脏读问题。其实,无论是脏写还是脏读,都是一个事务操作、读取另一个尚未提交的值,而那个事务可能回滚导致读取、操作的数据丢失。

不可重复读

  两个事务同时读取、修改同一行数据,事务 A 在事务期间多次读取数据行,事务 B 修改原始值 null 为值 B。假设多个事务之间不会发生脏读,即事务 A 不会读取到事务 B 尚未提交的值。

  事务 A 首次读取到原始值 null。

  之后事务 B 立即修改原始值 null 为值 B 并提交。

  这时事务 A 再次读取数据行变成了值 B。

  也就是说事务 A 在事务期间内读取同一行数据得到了不同的结果,原始值 null 被事务 B 修改为值 B,事务 A 不可能再重复读取到原始值 null,这就是所谓的不可重复读。如果说这是一个事务问题,一般场景下期望在事务内多次读取都是同一个值;但是在某些场景下,就是期望读取到其它事务对这个值的修改,比如说对某个状态字段的监听。

幻读

  两个事务对表中的数据进行操作,事务 A 在事务期间内多次查询表中的数据,事务 B 会向表中插入数据。

  事务 A 使用 SQL 语句 "select * from table where id > 10" 首次查询时,会查询出 12 条数据;

  这时事务 B 向表中插入了 2 条数据并提交;

  事务 A 再次查询时,查出了 14 条数据;

  也就是说,事务 A 在事务期间的多次查询,每次返回的结果都不一样,这就是所谓的幻读,“事务 A 中了幻术,每次眨眼都看到不一样的结果”。

posted @   维维尼~  阅读(263)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· DeepSeek “源神”启动!「GitHub 热点速览」
· 上周热点回顾(2.17-2.23)
点击右上角即可分享
微信分享提示