什么是事务?
事务:将多个操作封装到一个不可分割的执行单元,只有所有操作都执行成功才提交,只要其中任一操作执行失败,所有操作都回滚。
要么都做,要么都不做。
事务四大特性: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。