首先需要明确事务的概念:一组原子性的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. 一个优秀的http实现框架

    package com.ming; import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unir ...

  2. 【HDOJ】3832 Earth Hour

    其实就是bfs,不过也可以写成最短路,因为权重为1,可以用Spira解. /* 3832 */ #include <iostream> #include <string> #i ...

  3. wcf异常汇总

    1.确保客户端可以接收到服务端的异常 2.部署wcf出错,http错误404.3 3.无法自动调试 未能调试远程过程.这通常说明未在服务器上启用调试 WCF 托管在IIS上 4.ChannelFact ...

  4. POJ2676 Sudoku(dfs)

    题目链接. 题目大意: 就是数独游戏.横竖,每一个9宫方块,必须有1~9,且不重复. 分析: 直接DFS.一开始在原图上搜,会TLE.把要补全的空格,放入数组,这样就不用遍历整个图寻找要填的空格了. ...

  5. POJ_2914_Minimum_Cut_(Stoer_Wagner)

    描述 http://poj.org/problem?id=2914 求无向图中最小割. Minimum Cut Time Limit: 10000MS   Memory Limit: 65536K T ...

  6. ActionBar 中setDisplayHomeAsUpEnabled和setHomeButtonEnabled和setDisplayShowHomeEnabled方法的理解

    setHomeButtonEnabled这个小于4.0版本的默认值为true的.但是在4.0及其以上是false,该方法的作用:决定左上角的图标是否可以点击.没有向左的小图标. true 图标可以点击 ...

  7. objective-c中点语法的使用

    点语法的作用:提供一种访问属性的setter和getter的机制. 用法举例: 1.创建一个Person类,并声明属性.在person.h中. 2.实现一个init方法,并使用点语法等.在pers.m ...

  8. Spring学习总结

    spring是当前流行的一个框架.在学习spring之前当然的先准备一些jar包.可以在官网找找,(也可以留言,网盘分享): 基于IDEA环境学习. 第一天完成的任务: 1.使用spring框架输出一 ...

  9. 【JAVA - SSM】之MyBatis插入数据后获取自增主键

    很多时候,我们都需要在插入一条数据后回过头来获取到这条数据在数据表中的自增主键,便于后续操作.针对这个问题,有两种解决方案: (1)先插入,后查询.我们可以先插入一条数据,然后根据插入的数据的各个字段 ...

  10. js去除空格

    function trim(str){ return str.replace(/(^\s*) | ( \s*$ )/g,"" ); }