数据库ACID、隔离级别与MVCC
首先需要明确事务的概念:一组原子性的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的更多相关文章
- 数据库事务ACID/隔离级别
参考博客 1. 事务的定义 事务是用户定义的一个数据库操作序列.这些操作要么全执行,要么全不执行,是一个不可分割的工作单元.在关系型数据库中,事务可以是一条SQL语句,也可以是一组SQL语句或整个程序 ...
- Mysql数据库事务隔离级别
事务(transaction)是数据库管理系统的执行单位,可以是一个数据库操作(如Select操作)或者是一组操作序列.事务ACID属性,即原子性(Atomicity).一致性(Consistency ...
- MySQL四种隔离级别和MVCC
事务在一个数据库中的地位尤为重要,尤其是高并发的场合.保证数据库操作的原子性和错误出现情况下的回滚,对数据的安全性和可靠性提供了保障.事务有四大原则,即ACID原则.网上关于这个问题的文章有很多,读者 ...
- 一文读懂MySQL的事务隔离级别及MVCC机制
回顾前文: 一文学会MySQL的explain工具 一文读懂MySQL的索引结构及查询优化 (同时再次强调,这几篇关于MySQL的探究都是基于5.7版本,相关总结与结论不一定适用于其他版本) 就软件开 ...
- MySQL——事务ACID&隔离级别
数据库事务ACID&隔离级别 什么是事务 事务是用户定义的一个数据库操作序列.这些操作要么全执行,要么全不执行,是一个不可分割的工作单元.在关系型数据库中,事务可以是一条SQL语句,也可以是一 ...
- 数据库事务隔离级ORACLE数据库事务隔离级别介绍
本文系转载,原文地址:http://singo107.iteye.com/blog/1175084 数据库事务的隔离级别有4个,由低到高依次为Read uncommitted.Read committ ...
- mysql事务之一:MySQL数据库事务隔离级别(Transaction Isolation Level)及锁的实现原理
一.数据库隔离级别 数据库隔离级别有四种,应用<高性能mysql>一书中的说明: 然后说说修改事务隔离级别的方法: 1.全局修改,修改mysql.ini配置文件,在最后加上 1 #可选参数 ...
- [原创]java WEB学习笔记78:Hibernate学习之路---session概述,session缓存(hibernate 一级缓存),数据库的隔离级别,在 MySql 中设置隔离级别,在 Hibernate 中设置隔离级别
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- 4.事务提交过程,交易的基本概念,Oracle交易周期,保存点savepoint,数据库的隔离级别
事务提交过程 事务 基本概念 概念:一个或者多个DML语言组成 特点:要么都成功.要么都失败 事务的隔离性:多个client同一时候操作数据库的时候.要隔离它们的操作, 否则出现:脏读 不可反 ...
- 数据库事务隔离级别+Spring 声明性事务隔离级别
数据库事务隔离级别 数据库提供了四种事务隔离级别, 不同的隔离级别采用不同的锁类开来实现. 在四种隔离级别中, Serializable的级别最高, Read Uncommited级别最低. 大多数数 ...
随机推荐
- 【HDOJ】1059 Dividing
多重背包. #include <stdio.h> #include <string.h> #define mymax(a, b) (a>b) ? a:b ]; ]; vo ...
- POJ_3662_Telephone_Lines_(二分+最短路)
描述 http://poj.org/problem?id=3662 给一张图,要将1与n连起来.可以有k条边免费,其他边自费,付费的值为所有自费边中最大的值.求最小付费. Telephone Line ...
- BJOI2006狼抓兔子
1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 9967 Solved: 2267[Submit][S ...
- 牛刀小试、用SharePoint 实现请假管理功能
转:http://www.cr173.com/html/15518_1.html "请假管理"应用,应该算是 SharePoint 的"Hello World!" ...
- Delphi的BPL介绍和使用 转
了解BPL和DLL的关系将有助于我们更好地理解DELPHI在构件制作.运用和动态.静态编译的工作方式.对初学DELPHI但仍对DELPHI开发不甚清晰的朋友有一定帮助.BPL vs. DLL(原文ht ...
- Bzoj 1853: [Scoi2010]幸运数字 容斥原理,深搜
1853: [Scoi2010]幸运数字 Time Limit: 2 Sec Memory Limit: 64 MBSubmit: 1774 Solved: 644[Submit][Status] ...
- hdu 单调队列
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4122 代码: #include<cstdio> #include<iostream& ...
- Java Servlet 工作原理问答
导读 本文来自stackoverflow的问答,讨论了Java Servlet的工作机制,如何进行实例化.共享变量和多线程处理. 问题:Servlet是如何工作的?Servlet 如何实例化.共享变量 ...
- Yii PHP 框架分析(四)
作者:wdy http://hi.baidu.com/delphiss/blog/item/c15b314f05f9dfc0d0c86a26.html Yii应用的入口脚本最后一句启动了WebAppl ...
- AVL树的左旋右旋理解 (转)
AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下都是O(log n).增加和删除可能需要通过一次或多 ...