一直以来对数据库的事务隔离机制的理解总是停留在表面,其内容也是看一遍忘一边。这两天决定从原理上理解它,整理成自己的知识。查阅资料的过程中发现好多零碎的概念假设串起来足够写一本书,所以在这里给自己梳理一个脉络,详细的内容參考引文或在网上搜一下。因为平时接触最多的是MySQL。所以文章中某些部分是MySQL特有的特性,请读者注意。

数据库并发操作会引发的问题:

多个事务同一时候訪问数据库时候,会发生下列5类问题,包含3类数据读问题(脏读,不可反复读。幻读)。2类数据更新问题(第一类丢失更新,第二类丢失更新):
  1. 脏读(dirty read):A事务读取B事务尚未提交的更改数据。并在这个数据基础上操作。

    假设B事务回滚,那么A事务读到的数据根本不是合法的。称为脏读。

    在oracle中,因为有version控制,不会出现脏读。

  2. 不可反复读(unrepeatable read):A事务读取了B事务已经提交的更改(或删除)数据。比方A事务第一次读取数据,然后B事务更改该数据并提交,A事务再次读取数据,两次读取的数据不一样。
  3. 幻读(phantom read):A事务读取了B事务已经提交的新增数据。注意和不可反复读的差别。这里是新增,不可反复读是更改(或删除)。这两种情况对策是不一样的,对于不可反复读,仅仅须要採取行级锁防止该记录数据被更改或删除。然而对于幻读必须加表级锁。防止在这个表中新增一条数据。
  4. 第一类丢失更新:A事务撤销时。把已提交的B事务的数据覆盖掉。
  5. 第二类丢失更新:A事务提交时,把已提交的B事务的数据覆盖掉。

数据库在并发操作下会出现上述这些问题,要解决它就要想办法在运行可能引发问题的操作之前将该操作堵塞住,让它等到合适的时机再运行。

那么怎样挑选合适的时机堵塞操作的运行。又怎样保证在调度过程运行完毕后其运行结果与串行运行操作的结果同样呢?

三级封锁协议

数据库想要在“合适”的时机堵塞住数据库操作,那么首先要定义好怎么样的时机算是“合适”,由于各个系统支持的业务千差万别,对数据的实时性和有效性的要求也不同。

于是数据库理论中就提出了封锁级别的概念,对不同的同步要求採用不同的封锁级别。

三级封锁协议内容例如以下:

  • 一级封锁协议:事务T在改动数据R之前必须先对其加X锁,直到事务结束才释放。事务结束包含正常结束(COMMIT)和非正常结束(ROLLBACK)。

    一级封锁协议能够防止丢失改动,并保证事务T是可恢复的。使用一级封锁协议能够解决丢失改动问题。在一级封锁协议中。假设不过读数据不正确其进行改动。是不须要加锁的,它不能保证可反复读和不读“脏”数据。

  • 二级封锁协议:一级封锁协议加上事务T在读取数据R之前必须先对其加S锁。读完后方可释放S锁。

    二级封锁协议除防止了丢失改动,还能够进一步防止读“脏”数据。但在二级封锁协议中,因为读完数据后就可以释放S锁,所以它不能保证可反复读。

  • 三级封锁协议 :一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,直到事务结束才释放。

    三级封锁协议除防止了丢失改动和不读“脏”数据外,还进一步防止了不可反复读。

事务隔离级别:

三级封锁协议反映在实际的数据库系统上。就是四级事务隔离机制。

总的来说,四种事务隔离机制就是在逐渐的限制事务的自由度,以满足对不同并发控制程度的要求。下面就是数据库的四种隔离级别:

Read Uncommitted、Read Committed、Repeatable Read、Serializable

其对各个并发问题的制约强度见下表:

√: 可能出现    ×: 不会出现

  脏读 不可反复读 幻读
Read uncommitted
Read committed ×
Repeatable read × ×
Serializable × × ×

四种级别对并发问题的解决由弱到强。对应的系统性能由强到弱,MySQL的默认级别是Repeatable Read。

Read Uncommitted

在Read Uncommitted策略下,数据库遵循一级封锁协议,仅仅对改动数据的并发操作做限制。一个事务不能改动其它事务正在改动的数据,但能够读取到其它事务中尚未提交的改动,这些改动假设未被提交。将会成为脏数据。

Read committed

在Read committed策略下,数据库遵循二级封锁协议。仅仅同意读取已经被提交的数据,反过来讲,假设一个事务改动了某行数据且尚未提交。而第二个事务要读取这行数据的话,那么是不同意的。

在MySql的InnoDB下,尽管这样的操作不被同意。但MySQL不会堵塞住数据的查询操作,而是会查询出数据被改动之前的备份。返回给client。MySQL的这样的机制称为MVCC(多版本号并发控制),就是说数据库在事务并发的过程中对数据维护多个版本号,使得不同的事务对不同的数据版本号进行读写(MVCC的实现參见引用中的文章)。这样的机制反映在应用中就是,在不论什么时候对数据库查询总是能够得到数据库中近期提交的数据。为被提交的脏数据被隔离起来,无法被查询到,即防止脏读发生。

Repeat Read

Repeat Read又比Read Committed更加严格一点。但仍然是在二级封锁协议的范畴,仅仅是读取过程受到很多其它MVCC的影响。在Read Committed下,同意一个事务中多次同样查询得到不同的结果,就是所谓的不可反复读问题。这在一些应用中是同意的。所以oracle、SQL server上默认这一隔离级别。但MySQL没有。它默认Repeat Read级别。在这一级别下,有赖于MVCC,同一个事务中的查询仅仅能查到版本号号不高于当前事务版本号的数据,即事务仅仅能看到该事务開始前或者被该事物影响的数据。反过来说。这一级别下,不同意事务读取在该事务開始后新提交的数据。即防止了不可反复读的发生。

依靠上面的机制,已经做到了在事务内数据内容的不变,可是不能保证多次查询得到的数据数量一致。由于在一个事务运行的过程中别的事务全然能够运行数据插入。当插入了刚好符合查询条件的数据时,就会引发数据查询结果集添加。引发幻读。

另一种情况就是。假设一个事务想插入一条数据,而另一个事务已经插入了含有同样主键的数据,那么当前事务也会被堵塞,并终于运行失败,尽管当前事务根本无法查询到这一条数据,这也是一种幻读。

InnoDB提供的间隙锁机制能够在一定程度上防止幻读的发生。详细介绍见最后一篇引文。

Serializable

最后,最强事务隔离机制Serializable,它遵循三级封锁协议,使得全部的事务必须串行化运行,仅仅要有事务在对表进行查询,那么在此事务提交前,不论什么其它事务的改动都会被堵塞。这攻克了一切并发问题。但会造成大量的等待、堵塞甚至死锁。使系统性能减少。

要注意,在不论什么一种隔离机制下,都是不同意一个事务删除或改动还有一个事务影响过而未提交的数据的。由于事务增、删、改数据以后,会在该行加上排它锁,排它锁会堵塞其它事务再次对该行数据操作。也正是由于排它锁的存在,这四种隔离机制都不会出现不论什么一种更新丢失的现象,由于一条信息根本不同意第二个事务进行改动。

两段锁协议

数据库在调度并发事务时遵循“两段锁”协议,“两段锁”协议是指全部事务必须分两个阶段对数据项进行加锁和解锁

  1. 扩展阶段:在对不论什么数据项的读、写之前,要申请并获得该数据项的封锁。
  2. 收缩阶段:每一个事务中,全部的封锁请求必须先于解锁请求。

在数学上能够证明。遵循两段锁的调度能够保证调度结果与串行化调度同样。

这种机制保证了数据库并发调度与串行调度的等价。

*注:

參考资料:

http://blog.csdn.net/fg2006/article/details/6937413

http://blog.csdn.net/chen77716/article/details/6742128

http://www.2cto.com/database/201304/201415.html

http://snailxr.iteye.com/blog/1143615

http://blog.sina.com.cn/s/blog_711b11fd0101bhks.html

http://blog.sina.com.cn/s/blog_499740cb0100ugs7.html

转载请注明出处:

http://blog.csdn.net/gklifg/article/details/38752691

理解MySql事务隔离机制、锁以及各种锁协议的更多相关文章

  1. 五分钟后,你将真正理解MySQL事务隔离级别!

    什么是事务? 事务是一组原子性的SQL操作,所有操作必须全部成功完成,如果其中有任何一个操作因为崩溃或其他原因无法执行,那么所有的操作都不会被执行.也就是说,事务内的操作,要么全部执行成功,要么全部执 ...

  2. [MySQL数据库之事务、读现象、数据库锁机制、多版本控制MVCC、事务隔离机制]

    [MySQL数据库之事务.读现象.数据库锁机制.多版本控制MVCC.事务隔离机制] 事务 1.什么是事务: 事务(Transaction),顾名思义就是要做的或所做的事情,数据库事务指的则是作为单个逻 ...

  3. 详解Mysql事务隔离级别与锁机制

    一.概述 我们的数据库一般都会并发执行多个事务,多个事务可能会并发的对相同的一批数据进行增删改查操作,可能 就会导致我们说的脏写. 胀读和不可重复读.幻读这些问题. 这些问题的本质都是数据库的多事务并 ...

  4. 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景?

    在日常开发中,尤其是业务开发,少不了利用 Java 对数据库进行基本的增删改查等数据操作,这也是 Java 工程师的必备技能之一.做好数据操作,不仅仅需要对 Java 语言相关框架的掌握,更需要对各种 ...

  5. 第36讲 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景

    在日常开发中,尤其是业务开发,少不了利用 Java 对数据库进行基本的增删改查等数据操作,这也是 Java 工程师的必备技能之一.做好数据操作,不仅仅需要对 Java 语言相关框架的掌握,更需要对各种 ...

  6. 查询mysql事务隔离级别

    查询mysql事务隔离级别 查询mysql事务隔离级别 分类: DB2011-11-26 13:12 2517人阅读 评论(0) 收藏 举报 mysqlsessionjava   1.查看当前会话隔离 ...

  7. 轻松理解MYSQL MVCC 实现机制

    轻松理解MYSQL MVCC 实现机制 转载https://blog.csdn.net/whoamiyang/article/details/51901888 1. MVCC简介 1.1 什么是MVC ...

  8. Mysql事务-隔离级别

    MYSQL事务-隔离级别 事务是什么? 事务简言之就是一组SQL执行要么全部成功,要么全部失败.MYSQL的事务在存储引擎层实现. 事务都有ACID特性: 原子性(Atomicity):一个事务必须被 ...

  9. [51CTO]新说MySQL事务隔离级别!

    新说MySQL事务隔离级别! 事务隔离级别这个问题,无论是校招还是社招,面试官都爱问!然而目前网上很多文章,说句实在话啊,我看了后我都怀疑作者弄懂没!本文所讲大部分内容,皆有官网作为佐证,因此对本文内 ...

随机推荐

  1. IDEA界面创建Scala的Maven项目

    1. 创建Maven工程,勾选右侧的Create from archetype选项,然后选中下方的scala-archetype-simple选项,如图所示:2. 填写相应的GroupId.Artif ...

  2. python学习-- 数据库迁移 python manage.py makemigrations 和 python manage.py migrate

    python manage.py makemigrations 和 python manage.py migrate

  3. 听说你的模型损失是NaN

    听说你的模型损失是NaN 有时候,模型跑着跑着,损失就莫名变NaN了.不过,经验告诉我们,大部分NaN主要是因为除数是0或者传给log的数值不大于0.下面说说是log出NaN的几种常见解决方法. 毕竟 ...

  4. 九度oj 题目1513:二进制中1的个数

    题目描述: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 输入: 输入可能包含多个测试样例. 对于每个输入文件,第一行输入一个整数T,代表测试样例的数量.对于每个测试样例输入为一个 ...

  5. 解决Failure to transfer org.apache.maven.plugins:maven-surefire-plugin:pom:2.7

    一般情况下可能是文件格式有问题,将正确的文件内容替换掉错误的文件内容,不断地尝试,直到文件不报错,当然也有可能是下面的原因:下面是2.7.1版本的方法,其他类似) 或者是:进入该jar包指示的路径,删 ...

  6. CS231n笔记 Lecture 2 Image Classification pipeline

    距离度量\(L_1\) 和\(L_2\)的区别 一些感性的认识,\(L_1\)可能更适合一些结构化数据,即每个维度是有特别含义的,如雇员的年龄.工资水平等等:如果只是一个一般化的向量,\(L_2\)可 ...

  7. Luogu【P1725】琪露诺(单调队列,DP)

    本文是笔者第二篇解题报告.从现在开始,会将练的一些题发到博客上并归类到"解题报告"标签中. 琪露诺是这样一道题 这道题可以用纯DP做,但是据说会超时.(为什么?看起来过河这题比它数 ...

  8. [luoguP2601] [ZJOI2009]对称的正方形(二维Hash + 二分 || Manacher)

    传送门 很蒙蔽,不知道怎么搞. 网上看题解有说可以哈希+二分搞,也有的人说用Manacher搞,Manacher是什么鬼?以后再学. 对于这个题,可以从矩阵4个角hash一遍,然后枚举矩阵中的点,再二 ...

  9. QTREE系列题目总结

    $QTREE$ 就是一套树上数据结构练习题. 这套题貌似来源于 $SPOJ$,我是在 $luogu$ 看到的. $QTREE1$ 题意 一棵 $n$ 个点的带边权树,要求支持 单边改权值 和 询问路径 ...

  10. java面试题之volatile的工作原理

    volatile的特性: volatile可见性:对一个volatile的读,总可以看到对这个变量最终的写: volatile原子性:volatile对单个读/写具有原子性(32位Long.Doubl ...