MySQL事务特性与隔离级别以及事务分类

本文最后更新于:2022年7月24日 晚上

概览:MySQL事务

事务四大特性 ACID

数据库隔离级别

事务的分类

事务分类:

  1. 扁平事务
  2. 带有保存点的扁平事务
  3. 链事务
  4. 嵌套事务
  5. 分布式事务

1.扁平事务

最简单的一种事务,也是生产环境中最频繁的事务。

扁平的意思:所有的操作都处于同一层次之中,期间的操作是原子的,要么都执行,要么都回滚。

缺点:不能提交或者回滚事务的某一部分,或者想要分步骤提交事务时,都是不支持的。

2.带有保存点的扁平事务

允许在事务执行过程中回滚到同一个事务中的较早的一个状态。

因为某些事务在执行过程中出现错误,但是这不一定会导致所有的操作都无效,放弃整个事务的开销就有点大了。

使用保存点来记录事务的某个状态,发生错误的时候

3.链事务

快照读与当前读

现在假设一个抽奖活动项目,如果两个用户同时抽奖,而且同时中奖。两者都进入了中奖的事务。A事务扣减了奖品数量,B也执行了扣减数量。假设奖品数量是N,如果是可重复读,那么,如果两个事务并行进行,那么不论A有没有提交,B读到的数量都是N,执行后为N-1,而事务A也是N-1,这样不就有问题了吗?我们期望的是N-2。
那么实际上会出现这样的问题吗?
可以了解一下:快照读当前读

在事务中,执行普通select查询之后,会创建快照,后面再执行相同的select语句时,查询的其实是前面生成的快照。这也就是为什么会有可重复读。

如果执行下列语句的话

select * from table where ? lock in share mode;
select * from table where ? for update;
insert into table values (…);
update table set ? where ?;
delete from table where ?;

会执行当前读,获取最新数据。回到前面的问题,如果事务B执行N-1操作,会触发当前读,读取事务A提交后的数据,也就是N-1,在此基础上执行-1操作,最终N变成N-2。

这种场景下会遇到另一个问题:并发更新

上面解决了事务A已经提交的额情况。但如果事务A更新奖品数量后但还未提交呢?此时事务B执行当前读拿到的也是N啊。了解数据库锁机制的话,就不会有这种困惑了。事务A提交前,会一直持有排他锁(具体是行锁还是表锁,要看查询条件有没有走索引),此时事务B更新是会阻塞的。也就是说,只有事务A提交,或回滚之后,事务B才能获得排它锁,从而进行更新奖品的操作。

参考链接:https://blog.csdn.net/gu_wen_jie/article/details/88540918


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!