首先需要明确事务的概念:一组原子性的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. 【Node】SuperAgent

    What is the current mechanism to construct a query string with SuperAgent?http://stackoverflow.com/q ...

  2. FusionCharts 3.2.1 flash 图表展示、数据钻取

    StackedColumn3DLineDY.swf 效果展示: 一.页面代码 <div id="chart2div" align="center" sty ...

  3. js 打印网页指定内容

    function doPrint() { setTimeout(function() { bdhtml=window.document.body.innerHTML; sprnstr="&l ...

  4. Response.Write,Page.RegisterClientScriptBlock和Page.RegisterStartupScript的区别

    Response.Write("<script>");输出在文件头部,一打开就执行. RegisterClientScriptBlock一般返回的是客户端函数的包装, ...

  5. Eclipse SVN插件安装与使用(2014.12.27——by小赞)

    安装参考:http://www.cnblogs.com/xdp-gacl/p/3497016.html 用法参考:http://blog.sina.com.cn/s/blog_8a3d83320100 ...

  6. [LeetCode] 287. Find the Duplicate Number 解题思路

    Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), pro ...

  7. Installing Ubuntu on a Pre-Installed Windows 8 (64-bit) System (UEFI Supported)

    http://askubuntu.com/questions/221835/installing-ubuntu-on-a-pre-installed-windows-8-64-bit-system-u ...

  8. TabHost自定义外观

    博客园:http://www.cnblogs.com 农民伯伯: http://www.cnblogs.com/over140 版本 新浪微博 weibo_10235010.apk 正文 一.效果图 ...

  9. 4 weekend110的textinputformat对切片规划的源码分析 + 倒排索引的mr实现 + 多个job在同一个main方法中提交

    好的,现在,来weekend110的textinputformat对切片规划的源码分析, Inputformat默认是textinputformat,一通百通. 这就是今天,weekend110的te ...

  10. 【Java重构系列】重构31式之封装集合

    2009年,Sean Chambers在其博客中发表了31 Days of Refactoring: Useful refactoring techniques you have to know系列文 ...