MYSQL事务篇(高级篇)
1.事务介绍:
- 一般是指要做的或所做的事情。 在计算机 术语 中是指访问并可能更新数据库中各种 数据项 的一个程序 执行单元 (unit)
2.数据库事务具有ACID四大特性。
- ACID是以下4个词的缩写:
- 原子性(atomicity) :事务最小工作单元,要么全成功,要么全失败 。
- 一致性(consistency): 事务开始和结束后,数据库的完整性不会被破坏 。
- 隔离性(isolation) :不同事务之间互不影响,四种隔离级别为RU(读未提交)、RC(读已提交)、RR(可重复读)、SERIALIZABLE (串行化)。
- 持久性(durability) :事务提交后,对数据的修改是永久性的,即使系统故障也不会丢失 。
3.隔离级别:
- 四种隔离级别分别为:
1)未提交读(READ UNCOMMITTED/RU) 如果一个事务读到了另一个未提交事务修改过的数据,那么这种 隔离级别 就称之为 未提交读 会产生脏读的情况
2) 已提交读(READ COMMITTED/RC) 不可重复读:一个事务因读取到另一个事务已提交的update。导致对同一条记录读取两次以上的结果不一致。
如果一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值,那么这种 隔离级别 就称之为 已提交读,会产生幻读的情况。
3)可重复读(REPEATABLE READ/RR) 在一些业务场景中,一个事务只能读到另一个已经提交的事务修改过的数据,但是第一次读过某条记录后,
即使其他事务修改了该记录的值并且提交,该事务之后再读该条记录时,读到的仍是第一次读到的值,而不是每次都读到不同的数据。那么这种 隔离级别 就称之为 可重复读,会产生幻读的情况。
4)串行化(SERIALIZABLE) 最高的默认级别,强制事务串行执行(即一个事务一个事务执行)。效率极其低下。
幻读:一个事务因读取到另一个事务已提交的insert数据或者delete数据。导致对同一张表读取两次以上的结果不一致。
不可重复读: 一个事务因读取到另一个事务已提交的update。导致对同一条记录读取两次以上的结果不一致。
4.讲讲事务和MVCC底层原理详解:
比如现在有一个例子:
一个转账的一个案例:
丢失更新
4.1解决方案:LBCC:
4.2:解决方案2:MVVC:
5.Mysql的MVCC实现(重点):
- MVCC是用于数据库提供并发访问控制的并发控制技术MVCC最大的好处:相信也是耳熟能详:读不加锁,读写不冲突。
- 多版本并发控制仅仅是一种技术概念,并没有统一的实现标准,
- 其核心理念就是数据快照,不同的事务访问不同版本的数据快照,从而实现不同的事务隔离级别。
5.1MVVC的实现机制:
mvvc是通过undo log+readview实现的:
undo log:
- 是一个回滚日志就是提交一些未提交操作的原始状态 然后它会记录版本号 :
- 如果有主键是2个隐藏列 如果没有则是3个隐藏列
- 隐藏列呢就是三个部分组成
- 1.rowid:如果没有主键则会自动生产
- 2.回滚指针:指向记录的上一个版本号
- 3.事务id:记录了操作这条事务的id(这个id是唯一的而且是自增的) 然后每次更新都会有生产一个新版本通过回滚指针指向旧版本 形成一个版本链
- 执行删除操作的时候是不会直接删除的是进行了一个打了一个删除标记,真正删除是通过purge线程执行清除操作的
ReadView:
-
相当于一个快照,只要readview不改变则读取的结果就是一样的
- readview生产时刻就是执行select操作时生产的一个select对应一个ReadView select执行完毕那么ReadView就会失效
- 它就是一个数组(m_ids) 记录了当前时刻数据库活跃的事务id列表,它的可见性判断呢可以根据m_ids与事务id进行判断 判断条件可以根据(如果都可读以最新版本为准):
句个列子比如:
如果数据库没有活跃的事务,那么ReadView(m_ids)中包含的就是将要生成的事务id。
在REPEATABLE READ(RR)隔离级别下,MVCC具体是如何操作的。
MVCC是如何解决隔离级别的呢?
RC事务隔离级别的实现:
读已提交:当前事务可以读取其他事务提交的结果
实现方案:当前事务执行select语句时会生产一个ReadView,如果再次执行这个selct语句继续生成ReadView。
RR事务隔离级别的实现:
可重复读:当前事务中执行的select语句的多次执行结果都是相同的,不管其他事务有没有提交。
实现方案:在当前事务执行select语句生产一个ReadView,之后同一个select使用同一个ReadView
RC和RR的区别:
- READ COMMITTD 、 REPEATABLE READ 这两个隔离级别的一个很大不同就是生成 ReadView 的时机不同
- READ COMMITTD 在每一次进行普通 SELECT 操作前都会生成一个 ReadView
- 而 REPEATABLE READ 只在第一次进行普通 SELECT 操作前生成一个 ReadView ,之后的查询操作都重复这个 ReadView就好了。
- 在REPEATABLE READ隔离级别下,MVCC具体是如何操作的。