事务概念
https://segmentfault.com/a/1190000025156465
事务就是要保证一组数据库操作,要么全部成功,要么全部失败
在myssql中 事务是在引擎层实现的。
myISAM不支持事务,InnoDB支持事务
ACID
特性 | 含义 |
---|---|
A -Atomicity 原子性 | 事务包含的所有数据库操作要么全部成功,要不全部失败回滚 |
C -Consistency 一致性 | 一个事务执行之前和执行之后都必须处于一致性状态。拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性 |
I-Isolation 隔离性 | 一个事务未提交的业务结果是否对于其它事务可见。级别一般有:read_uncommit,read_commit,read_repeatable,Serializable 串行化访问。 |
D-Durability 持久性 | 一个事务一旦被提交了,那么对数据库中数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作 |
脏读 幻读 不可重复读
- 脏读 读到了其他事务未提交的数据
- 不可重复读 指的是在一个事务内,最开始读到的数据和事务结束前的任意时刻读到的同一批数据出现不一致的情况
- 幻读 幻读和不可重复读,有点类似,但是表达的侧重点不一样。 例如事务 A 对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。此时,突然事务 B 插入了一条数据并提交了,当事务 A 提交了修改数据操作之后,再次读取全部数据,结果发现还有一条数据未更新,给人感觉好像产生了幻觉一样。这就是幻读
隔离级别
隔离级别越高,效率越低
*读未提交(Read uncommited)RU
事务对当前被读取的数据不加锁;
事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加行级共享锁,直到事务结束才释放。
*读提交(Read commited)RC
事务对当前被读取的数据加行级共享锁(当读到时才加锁),一旦读完该行,立即释放该行级共享锁;
*事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加行级排他锁,直到事务结束才释放。
可重复读 (Repeatable read)RR
事务在读取某数据的瞬间(就是开始读取的瞬间),必须先对其加行级共享锁,直到事务结束才释放;
事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加行级排他锁,直到事务结束才释放。
*串行化 (Serializable)
Serializable 是最高的事务隔离级别,同时代价也花费最高,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻读。
事务在读取数据时,必须先对其加表级共享锁 ,直到事务结束才释放;
事务在更新数据时,必须先对其加表级排他锁 ,直到事务结束才释放。
视图与隔离级别
隔离级别 | 视图 |
---|---|
RU | 无 |
RC | 视图在事务启动的时候创建,每次读取都会重新生成一个快照,总是读取行的最新版本。也因此事务中每次select也可以看到其它已commit事务所做的修改。 |
RR | SQL语句开始执行的时候创建 只有在本事务中对数据进行更改才会更新快照。也就是说,如果在本事务中已经执行了一次select,此时其它事务执行了更改数据的操作并已提交,那么你在本事务再次select时,你是看不到其它事务所做的更改 |
Serializable | 使用锁,无视图 |
MySQL默认RR隔离级别的原因
主要和MySQL主从复制相关,因为MySQL在主从复制过程中是通过binlog进行数据同步的,而MySQL早期只有statement这种binlog格式,这种格式下,binlog记录的是SQL语句的原文。所以在事务乱序的时候,就会导致备库在进行SQL回放之后,结果和主库不一致。
为了解决这个问题,MySQL采用了RR这种隔离级别,因为在RR中,会在更新数据的时候增加记录锁的同时增加间隙锁,可以避免事务乱序的情况发生。
为啥大厂都换为RC?
其一是提升并发,其二是减少死锁
https://blog.csdn.net/NoviceZ/article/details/124627347
事务隔离实现
MVCC
事务启动方式
①手动开启手动提交:当用户执行start transaction命令时(事务初始化),一个事务开启,当用户执行commit命令时当前事务提交。从用户执行start transaction命令到用户执行commit命令之间的一系列操作为一个完整的事务周期。若不执行commit命令,系统则默认事务回滚。
②自动开启自动提交:如果用户在当前情况下(参数autocommit=1)未执行start transaction命令而对数据库进行了操作,系统则默认用户对数据库的每一个操作为一个孤立的事务,也就是说用户每进行一次操作系都会即时提交或者即时回滚。这种情况下用户的每一个操作都是一个完整的事务周期。
MVCC
详细见 5 mysql MVCC