MySQL事务
ACID四个性质
并非任意的对数据库的操作序列都是数据库事务。数据库事务拥有以下四个特性,习惯上被称之为ACID特性。
- 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
- 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。
- 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
- 持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中
四大隔离级别
- 读未提交(Read Uncommitted):锁在事务操作后释放
- 读已提交(Read Committed):锁在事务提交后释放
- 可重复读(Repeatable-Read):锁在事务提交后释放
- 序列化(serializable)
可重复读和不可重复读:事务A中包含两次读取同一个数据x,事务B包含对数据x进行修改的操作。在进行事务A时同时进行了事务B,则可能发生:在事务A中第一次与第二次读取的同一个数据不同则称为不可重复读,相同则称为可重复读。
脏读:事务A第一次读取x,事务B对x进行了修改但是没有提交事务,此时事务A第二次读取x,读取的数值不一样,而与此同时事务B由于某个操作失败进行了回滚(此时x并没有修改)。那么事务A第二次读取的x就是一个脏数据。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | 可能 | 可能 | 可能 |
读已提交 | 不可能 | 可能 | 可能 |
可重复读 | 不可能 | 不可能 | 避免了幻读 |
序列化 | 不可能 | 不可能 | 不能 |
为了防止同事务中两次读取数据不一致,(包括不可重读和幻读),MySQL采用mvcc并发版本控制
如果事务中存在多次读取同样的数据,MySQL第一次读的时候仍然会保持选择读最新提交事务的数据,当第一次之后,之后再读时,mysql会取第一次读取的数据作为结果。这样就保证了同一个事务多次读取数据时数据的一致性。这时候,mysql把这种解决方案叫做:可重复读(Repeatable-Read),也就是上述所写的第三个隔离性,也是mysql默认的隔离级别。
注意:幻读和不可重复读(Read Committed)都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。
mysql默认级别RR下到底能不能防止幻读?
答案:mysql在范围查询下加了GAP锁,能避免。
官方采证:https://github.com/Yhzhtk/note/issues/42
undo log && redo log
原子性的原理:
1.undo log:原始数据的备份
首先记录原始数据到undo log,然后修改数据,最后三步:将undo log写入磁盘,将数据写入磁盘,事务提交。1.如果在undo log写入磁盘之前系统崩溃,数据还没有持久化到磁盘,所以磁盘上的数据还是保持在事务开始之前的状态。2.如果在数据写入磁盘和事务提交之间系统崩溃,则可以通过undo log回滚事务。
缺陷:每个事务提交前将数据和Undo Log写入磁盘,这样会导致大量的磁盘IO,因此性能很低。将数据缓存一段时间,减少IO提高性能。但是这样就会丧失事务的持久性。因此引入了另外一
种机制来实现持久化,即Redo Log.
2.redo log:更新数据后的备份
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 876208453@qq.com
文章标题:MySQL事务
本文作者:Cai Jun
发布时间:2019-01-31, 19:30:19
最后更新:2019-02-24, 13:01:26
原始链接:http://johncaijun.github.io/2019-02-01-MySQL事务/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。