从本质上来说,原子性也是为了配合持久性而存在的,当事务的一部分写入redo日志后,发生了崩溃、断电,那么根据原子性来说,该次事务应当恢复,那么对于已经持久化到日志文件中的数据,就必须要通过回溯来撤销。在InnoDB存储引擎中,redo重做日志对应的就是ib_logfile0、ib_logfile1。
接着,事务要进行回滚,那就需要通过一致性来保障,而undo日志就是用来实现一致性的,在undo日志中保存了多个版本的事务的一些信息,通过undo日志,将事务rollback到修改之前的样子。
在此,不得不提的是MySQL的MVCC多版本并发控制,它也是通过undo日志来实现的。
MVCC是通过在每一数据行后头添加2个隐藏字段create version、delete version以及每次开启一个事务会初始化一个事务id。新增一条数据的时候,create version的值就等于事务id,删除数据的时候,delete version就等于事务id,更新数据的时候会先删后增,在undo日志中就会存在2条数据,一条delete version就等于事务id,一条create version的值等于事务id。
在事务执行过程中,可能会同时存在其它的事务,而多个事务之前需要相互隔离,也就是要做到并发控制,锁就是用来实现隔离性的。MySQL的事务的隔离级别包含:Read Uncommitted读未提交、Read Committed读已提交、Read Repeatable可重复读、Serializable串行化。其中,读已提交、可重复读是基于MVCC多版本并发控制来实现的。
锁,为事务的并发控制带来了好处,同时也带来了坏处,包括:脏读、不可重复读、幻读。
脏读,指的是一个事务读到了另一个事务未提交的内容,一旦另一个事务回滚了,就出现了脏数据。
不可重复读,指的是同一个事务使用同一句SQL进行多次读取,返回不同的结果。
幻读,指的是一个事务在进行增删的时候,某些已经确定不会出现的记录突然出现。
要解决脏读,那就需要至少设置隔离级别为:Read Committed读已提交。
要解决不可重复读,那就需要至少设置隔离级别为:Read Repeatable可重复读。
要解决幻读,那就需要设置隔离级别为:Serializable串行化或者采用Next-Key Lock间隙锁。
以上就是浅析MySQL 锁和事务的详细内容,更多关于MySQL 锁和事务的资料请关注其它相关文章!
更多相关Mysql内容来自木庄网络博客
标签:Mysql
相关阅读 >>
mysql官方手册学习笔记2 mysql的模糊查询和正则表达式
更多相关阅读请进入《mysql》频道 >>

数据库系统概念 第6版
本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。