Mysql:事务的四大性质及解决
作者:互联网
- 事务的四大性质:
- 原子性:通过undolog日志文件实现
- 持久性:通过redo log实现
- 隔离性:通过锁和mvcc机制实现
- 一致性:通过上面三个实现
- 锁:
- 加锁会降低数据库读写效率
- 当前读:总是读取最新的数据
- 读锁(共享锁):select…lock in share mode
- 写锁(排它锁):select…for update、update、insert、delete
- 快照读:读取历史版本的一个记录
- 原子性:
- 事务2修改zhangsan为lisi,首先把zhangsan这个行记录添加排他锁,然后把zhangsna此时的行状态写入undolog,最后修改lisi的最近操作事务id与回滚指针
- undolog内容:事务id(单调递增),行id,回滚指针
-
当不同事务对同一记录做修改时,会导致该行记录的undolog形成一个线性表
-
现在有了事务4,那么事务4读取的是哪个版本的数据?一定有对应规则,规则是什么=》隔离级别。
-
隔离性:
-
readview:事务快照读时,产生的视图
-
假如4个事务都操作相同的记录,事务2能读到事务4修改的记录吗? 能
-
事务2下的开启改为开启并快照读
-
判断原则,可见性算法(判断为可提交则可读)
- 所以上面就是判断事务2在读快照时,事务4是否已提交。已提交则可读,未提交则不可读。(注意是读快照时)=》这就是读已提交RC
-
为什么RR,可重复读看不到?
-
和RC相比,readview生成的时机不同,因为就是把最近事务操作id和readview的值进行对比
-
trx_list 变成了 1234了,4在里面了,判断为事务4未提交。
-
RR级别下,事务2永远读的是第一次的快照吗? 不是
-
如果事务2 进行update操作(当前读),快照会更新(会找更新就会引起RC级别的幻读)
-
RR要解决幻读,需要借助间隙锁(锁一段范围),如select... for update,其他事务插入更新就会阻塞。(那自己不是还可以更新 readview)
-
总结:readview会更新就可能会幻读。
-
-
-
-
持久性:
-
先写日志,再写数据 :比如我们更一条数据
-
数据从磁盘找到这条数据(很慢,随机读),加载到内存,更新后写入磁盘
-
万一写入磁盘错误或者数据丢失,怎么恢复呢?
-
日志是以追加的形式进行读写(顺序读写)的,如果我们先把这条日志写入redolog,就不怕数据丢失了
-
-
二阶段提交:
- mysql本来就有个二进制日志文件binlog ,innodb这个插件引擎(undolog,redolog)的redolog必须和binlog保持一致
- 为什么会有prepare状态:
- 保证日志文件一致:如果再binlog前断电,日志文件不一致,回滚;在binlog下面断点,没事,把prepare改成commit就行。。。理解不太深
-
标签:事务,快照,undolog,readview,四大,提交,Mysql,日志 来源: https://blog.csdn.net/youaremyalllove/article/details/123191817