MySQL事务特性与隔离级别以及事务分类
本文最后更新于:2022年7月24日 晚上
概览:MySQL事务
事务四大特性 ACID
数据库隔离级别
事务的分类
事务分类:
- 扁平事务
- 带有保存点的扁平事务
- 链事务
- 嵌套事务
- 分布式事务
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 协议 ,转载请注明出处!