首先需要明确事务的概念:一组原子性的SQL查询,如果数据库引擎能够成功的对数据库应用该组查询的全部语句,那么就执行该组语句,否则所有语句都不执行。

事务有ACID四个特性,即:

原子性:一个事务是一个不可分割的最小工作单元,其操作要么全部成功,要么全部失败;

一致性:数据库总是从一个一致性状态转换为另一个一致性状态。所谓一致性状态,就是数据库的所有完整性约束(尤其注意用户定义约束)都被遵守,以银行转账为例,“转账操作必然导致一个账户减少金额,另一个账户增加金额,且这两个账户总金额之和不变”就是一个完整性约束。

持久性:一旦事务提交,则其所作的修改就会永久保存到数据库中

隔离性:隔离性用于定义事务之间的相互隔离程度,存在四个隔离级别。

首先需要解释一下几个跟隔离性相关的概念定义:

(1)脏读:指事务读到脏数据,所谓脏数据,指的是不正确的数据,例如事务执行过程中修改了某记录,然后回滚,如果其他事务读到了该记录的中间修改值,则为脏读。

(2)不可重复读:事务在执行过程中,多次对同一个已经存在的记录进行读取,各次读取的值不同。读提交隔离级别存在不可重复读的问题,事务1、2并发执行,事务2首先读取记录1,然后事务1修改记录1并提交,事务2继续读取记录1,则事务2两次读取到的值不同。

(3)幻读:幻读是指使用某个条件读取一批记录时,可能读到的记录数不同。幻读与脏读、不可重复读的区别在于,脏读、不可重复读都是针对某个确定的已经存在的记录出现的值不要求(读到脏数据或多次读的值不同),而幻读则是多次使用同一个条件查询一批记录,多次读到的记录数不同,也就是说,脏读、不可重复读是由于多个事务并行执行update引起的,而幻读则是由于多个事务并行执行insert引起的(并发delete引起的问题看起来算哪个都行……)。

四个隔离级别为:

(1)Read Uncommited:读未提交,其含义为多个并发事务,任何一个事务可以读到其他事务尚未提交的修改:

    存在脏读、不可重复读、幻读可能性。

(2)Read Commited:读已提交,含义为多个并发事务,任何一个事务只可以读到其他事务已经提交的修改:

    解决脏读,存在不可重复读、幻读可能性。

(3)Repeatable Read:可重复读,含义为多个事务并发执行时,任何一个事务反复读取已存在的记录,每次读到的值都是相同的

    解决脏读、不可重复读,存在幻读可能性。

(4)Serializable:串行化,含义为所有事务串行执行,因此不存在事务并发执行的情况。

    解决脏读、不可重复读、幻读。

多版本并发控制MVCC

上述四个隔离级别中,读未提交隔离性最差,且相对于读已提交,性能并没有多少提升,几乎不会使用;串行化隔离性最好,可是性能太差,也几乎不会使用。一般数据库的默认隔离级别要么是读已提交,要么是可重复读(例如MySQL的InnoDB引擎),要么是读已提交(例如Oracle )。

如果使用行级读锁、写锁来实现读已提交或可重复读,应当是以下的步骤:

1、事务1会修改行1,则会在行1加上写锁,开始事务;

2、事务2为纯读取操作,需要读取行1,试图在行1上加上读锁,由于事务1已加写锁,因此事务2等待直到事务1完成。

3、如果事务2先开始,则事务1也需要等到事务2完成并释放读锁后才可以开始执行。

也即使说,对某行的写操作会阻塞所有对该行的读取操作,对某行的读操作会阻塞所有对该行的写操作,在系统存在读、写并发时,不论系统IO能力有多高,会受限于锁而导致性能低下。

MVCC用于解决这个问题来提高系统性能,MVCC并没有统一的标准,各个数据库实现均采用不同方式来实现MVCC,InnoDB的实现方式如下:

准备工作:

(1)对每行记录增加行标志和删除标志两个字段;

(2)维护一个全局的系统版本号,每开始一个事务(注意select也是事务,读事务),将该系统版本号加1并作为事务的版本号

插入记录的行标志设置为本事务版本号,删除标志为空;

删除记录的删除标志设置为本事务版本号;

修改的处理过程:将原记录的删除版本号修改为本事务版本号;新插入一条记录,包含原记录数据及本次修改,行记录标志设置为本事务版本号,删除标志为空;

读取的处理过程:

仅读取同时满足以下条件的记录行:

(1)行标志小于或等于本事务版本号(等于用于保证能够读取到本事务内提交的增加);

(2)删除标志为空或者大于本事务版本号(不包括等于以保证不会读取到本事务删除的记录);

相当于在读事务开始的时刻点,建立了一个系统的快照,该事务读取的所有数据,均是从快照中读取的,因此满足可重复读的条件,并且可解决幻读的问题,并且也不会读到产生“同样查询条件,事务中第一次读到的记录数大于第二次读到的记录数的问题“(由并发删除引起)

从上可知,使用MVCC后,大部分读都不再需要加读锁,因此读不再阻塞写,写也不再阻塞读。读操作只再受限于系统IO能力。

数据库ACID、隔离级别与MVCC的更多相关文章

  1. 数据库事务ACID/隔离级别

    参考博客 1. 事务的定义 事务是用户定义的一个数据库操作序列.这些操作要么全执行,要么全不执行,是一个不可分割的工作单元.在关系型数据库中,事务可以是一条SQL语句,也可以是一组SQL语句或整个程序 ...

  2. Mysql数据库事务隔离级别

    事务(transaction)是数据库管理系统的执行单位,可以是一个数据库操作(如Select操作)或者是一组操作序列.事务ACID属性,即原子性(Atomicity).一致性(Consistency ...

  3. MySQL四种隔离级别和MVCC

    事务在一个数据库中的地位尤为重要,尤其是高并发的场合.保证数据库操作的原子性和错误出现情况下的回滚,对数据的安全性和可靠性提供了保障.事务有四大原则,即ACID原则.网上关于这个问题的文章有很多,读者 ...

  4. 一文读懂MySQL的事务隔离级别及MVCC机制

    回顾前文: 一文学会MySQL的explain工具 一文读懂MySQL的索引结构及查询优化 (同时再次强调,这几篇关于MySQL的探究都是基于5.7版本,相关总结与结论不一定适用于其他版本) 就软件开 ...

  5. MySQL——事务ACID&隔离级别

    数据库事务ACID&隔离级别 什么是事务 事务是用户定义的一个数据库操作序列.这些操作要么全执行,要么全不执行,是一个不可分割的工作单元.在关系型数据库中,事务可以是一条SQL语句,也可以是一 ...

  6. 数据库事务隔离级ORACLE数据库事务隔离级别介绍

    本文系转载,原文地址:http://singo107.iteye.com/blog/1175084 数据库事务的隔离级别有4个,由低到高依次为Read uncommitted.Read committ ...

  7. mysql事务之一:MySQL数据库事务隔离级别(Transaction Isolation Level)及锁的实现原理

    一.数据库隔离级别 数据库隔离级别有四种,应用<高性能mysql>一书中的说明: 然后说说修改事务隔离级别的方法: 1.全局修改,修改mysql.ini配置文件,在最后加上 1 #可选参数 ...

  8. [原创]java WEB学习笔记78:Hibernate学习之路---session概述,session缓存(hibernate 一级缓存),数据库的隔离级别,在 MySql 中设置隔离级别,在 Hibernate 中设置隔离级别

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  9. 4.事务提交过程,交易的基本概念,Oracle交易周期,保存点savepoint,数据库的隔离级别

     事务提交过程 事务 基本概念 概念:一个或者多个DML语言组成 特点:要么都成功.要么都失败 事务的隔离性:多个client同一时候操作数据库的时候.要隔离它们的操作, 否则出现:脏读  不可反 ...

  10. 数据库事务隔离级别+Spring 声明性事务隔离级别

    数据库事务隔离级别 数据库提供了四种事务隔离级别, 不同的隔离级别采用不同的锁类开来实现. 在四种隔离级别中, Serializable的级别最高, Read Uncommited级别最低. 大多数数 ...

随机推荐

  1. for嵌套for ★

    namespace for嵌套for五角星{    class Program    {        static void Main(string[] args)        {         ...

  2. POJ_3046_Ant_Counting_(动态规划,多重集组合数)

    描述 http://poj.org/problem?id=3046 n种蚂蚁,第i种有ai个,不同种类的蚂蚁可以相互区分,但同一种类的蚂蚁不能相互区分,从这些蚂蚁中取出s,s+1,s+2,...,b- ...

  3. Cocos2d-x学习之windows 7的visual studo 2010开发环境安装

    1.引擎代码的下载 官方版本地址为: http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Download 目前最新版本是cocos2d-2.0-rc0a ...

  4. MSW下wxWidgets的安装与编译

    教程摘自网上各大博客.贴吧.论坛,结合自己的实践做了一些实质性的修改. 一.安装 首先从http://sourceforge.net/projects/wxwindows/files/2.8.12/w ...

  5. RHEL6彻底禁用ip6的方法

    一.vi  /etc/modprobe.d/disable-ipv6.conf(名字随便起)(RHEL6.0之后没有了/etc/modprobe.conf这个文件) 输入:install ipv6 / ...

  6. Get familiar with key Frameworks of ios

    Frameworks make your life easier as an iOS Developer. They allow you to reuse code written by other ...

  7. openstack libtray

    OpenStack packages¶ Distributions release OpenStack packages as part of the distribution or using ot ...

  8. NTP DDOS攻击

    客户端系统会ping到NTP服务器来发起时间请求更换,同步通常每隔10分钟发生: 从NTP服务器发回到客户端的数据包可能比初始请求大几百倍.相比之下,通常用于放大攻击中的DNS响应被限制仅为8倍的带宽 ...

  9. 学习:Linux基础知识<一>

    >>硬盘分区模式 硬盘分区模式一般如下: -- /  (根目录) -- /usr    (操作系统) --/home (用户信息) -- /var    (默认服务器的登录文件,邮件与WW ...

  10. IIS- ASP站点布署时查看ASP错误信息

    ASP使用的脚本是VBSCRIPT,布置的时候想显示他的错误信息,可以在INTERNET选项里把显示友好http错误信息的勾去掉 就能查看ASP布署时查看错误信息的勾去掉.