数据库-事务

本文深入探讨了数据库事务的ACID特性,包括原子性、持久性、隔离性和一致性。同时,介绍了并发事务可能导致的脏读、不可重复读和幻读问题以及四种隔离级别:读未提交、读已提交、可重复读和串行化。在MySQL中,可重复读隔离级别利用MVCC和间隙锁解决了幻读问题。通过对不同隔离级别的实例分析,帮助读者理解其在实际操作中的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是事务?

事务:将多个操作封装到一个不可分割的执行单元,只有所有操作都执行成功才提交,只要其中任一操作执行失败,所有操作都回滚。
要么都做,要么都不做。

事务四大特性:ACID

持久性(Durability)
一旦事务提交,则其所做的修改会永久保存到数据库。

原子性(Atomicity)
一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作,要么全部提交成功,要么全部失败回滚。

隔离性(Isolation)
并发环境中,并发的事务相互隔离,并发执行的各个事务之间不能相互干扰

一致性(Consistency)
事务执行的结果必须是:使数据库从一个一致性状态转变到另一个一致性状态。
原子性和隔离性都是保证一致性的一种手段

满足原子性和隔离性的操作一定就满足一致性么?
不一定,比如说A现在只有10块,要转账20元给B,虽然在满足原子性和隔离性,但转账完成了之后A的账户的余额就成负的了,这显然是不满足一致性的。
不满足原子性和隔离性的操作就一定不满足一致性么?
也不一定,只要最后的结果符合所有现实世界中的约束,那么就是符合一致性的。

并发事务导致的四种问题

脏写
当两个并发执行的事务更新同一行数据,有可能A事务会把B事务的更新数据覆盖掉。

脏读
如果A事务读到了B事务更新过的数据,但是B事务此时还未提交,并且B事务最终不是提交而是回滚,A事务读到的数据就被回滚掉了,不再是正确的数据而是脏数据

不可重复读
在事务A两次读取同一记录的过程中,事务B对该记录进行了修改,导致事务A两次读到的数据不一样

幻读
事务1在两次查询的过程中,事务2对该表其他记录做了修改,比如进行了插入、删除操作,从而事务1第二次查询的结果数量发生了变化。

脏读、不可重复读、幻读的区别
脏读:读的是尚未提交的数据然后被回滚导致数据是脏的
不可重复读 与 幻读都是读取的已经提交的数据,两次读取的同一数据不一致。
不可重复读指两次读同一行的数据不一致
幻读指一个事务在前后两次查询同一个范围的时候,两次查询的范围数据不一样。

四种隔离级别

1、读未提交:你修改了数据尚未提交,我就读了,但是你又回滚了事务,我就读到了脏数据,所以无法解决脏读问题

2、读已提交:你没提交我不读,你提交了我才去读,所以可以解决脏读。但是你修改前后我读到的不一样,所以不能解决重复读

3、可重复读:你修改了数据并且已经提交,我也不读。所以 解决脏读和不可重复读,但是如果你删除了其他的某行或插入新的一行数据,我查询表行数得到的数据也不一致,所以不能解决幻读( mysql的默认隔离级别,并且可以利用间隙锁+MVCC解决幻读)

4、串行化:事务不能并发执行,组成串一个一个排着队的执行。解决幻读

mysql在可重复读隔离级别下可以解决幻读的原理:
快照读的幻读——mvcc 解决,读当前快照,所以表中行数据变化无影响。
当前读的幻读——间隙锁解决,间隙锁保证不允许行数变化。

举例理解四种隔离级别:
在这里插入图片描述
我们来看看在不同的隔离级别下,事务 A 会有哪些不同的返回结果,也就是图里面 V1、V2、V3 的返回值分别是什么。

若隔离级别是“读未提交”,222

若隔离级别是“读提交”,122

若隔离级别是“可重复读”,112

若隔离级别是“串行化”,则在事务 B 执行“将 1 改成 2”的时候,会被锁住。直到事务 A 提交后,事务 B 才可以继续执行。所以从 A 的角度看, V1、V2 值是 1,V3 的值是 2。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值