【译】数据库事务隔离级别
看到wikipedia中文关于数据库相关的几个经典条目有点老旧,尤其和英文条目相比。确定开始翻译其中几篇,先从事务隔离等级开始。格式采用维基Sandbox发布后的格式。翻译完后自己校对过几遍,质量还可以。:-)
已经在中文维基发布。
翻译的中文条目地址:事务隔离等级;
对应的英文条目地址:Isolation (database systems)
欢迎大家指正,可以直接在维基上对应条目更新的!。
有些郁闷在英文的个人主页下面,里面的引用词条的链接都很正常但是维基中文发布后,里面的引用词条都不可用了。初步判断是中文词条和英文词条不是一个库。为了内部词条链接可用,转到博客的是我的英文的个人主页内的格式。
事务隔离(isolation)定义了数据库系统中一个操作产生的影响什么时候以哪种方式可以对其他并发操作可见。隔离是事务ACID (原子性、一致性性、隔离性、持久性)四大属性中的一个重要属性。
Contents
- 1 并发控制(Concurrency control)
- 2 隔离级别(Isolation levels)
- 2.1 可序列化(Serializable)
- 2.2 可重复读(Repeatable reads)
- 2.3 授权读(Read committed)
- 2.4 未授权读(Read uncommitted)
- 3 默认隔离级别
- 4 读现象(Read phenomena)
- 4.1 脏读(Dirty reads (Uncommitted Dependency))
- 4.2 不可重复读(non-repeatable read)
- 4.3 幻影读(phantom read)
- 5 隔离级别、读现象和锁(Isolation Levels, Read Phenomena and Locks)
- 5.1 隔离级别vs读现象(Isolation Levels vs Read Phenomena)
- 5.2 隔离级别vs 锁持续时间(Isolation Levels vs Lock Duration)
- 6 参照
- 7 相关条目
- 8 外部链接
并发控制(Concurrency control)
并发控制描述了数据库处理隔离以保证数据正确性的机制。为了保证并行事务执行的准确执行数据库和存储引擎在设计的时候着重强调了这一点。典型的事务相关机制限制数据的访问顺序(执行调度)以满足可序列化 和可恢复性。限制数据访问意味着降低了执行的性能,并发控制机制就是要保证在满足这些限制的前提下提供尽可能高的性能。经常在不损害正确性的情况下,为了达到更好的性能,可序列化的的要求会减低一些,但是为了避免数据一致性的破坏,可恢复性必须保证。
两阶段锁是关系数据库中最常见的提供了可序列化 和可恢复性的并发控制机制,为了访问一个数据库对象,事务首先要获得这个对象的 锁。对于不同的访问类型(如对对象的读写操作)和锁的类型,如果另外一个事务正持有这个对象的锁,获得锁的过程会被阻塞或者延迟。
隔离级别(Isolation levels)
在数据库事务的ACID四个属性中,隔离性是一个最常放松的一个。为了获取更高的隔离等级,数据库系统的 锁机制或者多版本并发控制机制都会影响并发。 应用软件也需要额外的逻辑来使其正常工作。
很多DBMS定义了不同的“事务隔离等级”来控制锁的程度。在很多数据库系统中,多数的数据库事务都避免高等级的隔离等级(如可序列化)从而减少对系统的锁定开销。程序员需要小心的分析数据库访问部分的代码来保证隔离级别的降低不会造成难以发现的代码bug。相反的,更高的隔离级别会增加死锁发生的几率,同样需要编程过程中去避免。
ANSI/ISO SQL定义的标准隔离级别如下。
可序列化(Serializable)
最高的隔离级别。
在基于锁机制并发控制的DBMS实现可序列化要求在选定对象上的读锁和写锁保持直到事务结束后才能释放。在SELECT 的查询中使用一个“WHERE”子句来描述一个范围时应该获得一个“范围锁(range-locks)”。这种机制可以避免“幻影读(phantom reads)”现象。
当采用不基于锁的并发控制时不用获取锁。但当系统探测到几个并发事务有“写冲突”的时候,只有其中一个是允许提交的。这种机制的详细描述见“'快照隔离”
可重复读(Repeatable reads)
在可重复读(REPEATABLE READS)隔离级别中,基于锁机制并发控制的DBMS需要对选定对象的读锁(read locks)和写锁(write locks)一直保持到事务结束,但不要求“范围锁(range-locks)”,因此可能会发生“幻影读(phantom reads)”
授权读(Read committed)
在授权读(READ COMMITTED)级别中,基于锁机制并发控制的DBMS需要对选定对象的写锁(write locks)一直保持到事务结束,但是读锁(read locks)在SELECT操作完成后马上释放(因此“不可重复读”现象可能会发生,见下面描述)。和前一种隔离级别一样,也不要求“范围锁(range-locks)”。
简而言之,授权读这种隔离级别保证了读到的任何数据都是提交的数据,避免读到中间的未提交的数据,脏读(dirty reads)。但是不保证事务重新读的时候能读到相同的数据,因为在每次数据读完之后其他事务可以修改刚才读到的数据。
未授权读(Read uncommitted)
未授权读(READ UNCOMMITTED)是最低的隔离级别。允许脏读(dirty reads),事务可以看到其他事务“尚未提交”的修改。
通过比低一级的隔离级别要求更多的限制,高一级的级别提供更强的隔离性。标准允许事务运行在更强的事务隔离级别上。(如在可重复读(REPEATABLE READS)隔离级别上执行授权读(READ COMMITTED)的事务是没有问题的)
默认隔离级别
不同的DBMS默认隔离级别也不同。多少数据库允许用户设置隔离级别。有些DBMS在执行一个SELECT语句时使用额外的语法来获取锁(如SELECT ... FOR UPDATE来获得在访问的数据行上的排他锁)
读现象(Read phenomena)
ANSI/ISO 标准SQL 92涉及三种不同的一个事务读取另外一个事务可能修改的数据的“读现象”。
下面的例子中,两个事务,事务1执行语句1。接着,事务2执行语句2并且提交,最后事务1再执行语句1. 查询使用如下的数据表。
id | name | age |
---|---|---|
1 | Joe | 20 |
2 | Jill | 25 |
脏读(Dirty reads (Uncommitted Dependency))
当一个事务允许读取另外一个事务修改但未提交的数据时,就可能发生脏读(dirty reads)。
脏读(dirty reads)和不可重复读(non-repeatable reads)类似。事务2没有提交造成事务1的语句1两次执行得到不同的结果集。在未授权读(READ UNCOMMITTED)隔离级别唯一禁止的是更新混乱,即早期的更新可能出现在后来更新之前的结果集中。
在我们的例子中,事务2修改了一行,但是没有提交,事务1读了这个没有提交的数据。现在如果事务2回滚了刚才的修改或者做了另外的修改的话,事务1中查到的数据就是不正确的了。
事务 1 | 事务 2 |
---|---|
/* Query 1 */ SELECT age FROM users WHERE id = 1; /* will read 20 */ |
|
/* Query 2 */ UPDATE users SET age = 21 WHERE id = 1; /* No commit here */ |
|
/* Query 1 */ SELECT age FROM users WHERE id = 1; /* will read 21 */ |
|
ROLLBACK; /* lock-based DIRTY READ */ |
在这个例子中,事务2回滚后就没有id是1,age是21的数据行了。
不可重复读(non-repeatable read)
在一次事务中,当一行数据获取两遍得到不同的结果表示发生了“不可重复读(non-repeatable read)”.
在基于锁的并发控制中“不可重复读(non-repeatable read)”现象发生在当执行SELECT 操作时没有获得读锁(read locks)或者SELECT操作执行完后马上释放了读锁; 多版本并发控制中当没有要求一个提交冲突的事务回滚也会发生“不可重复读(non-repeatable read)”现象。
事务 1 | 事务 2 |
---|---|
/* Query 1 */ SELECT * FROM users WHERE id = 1; |
|
/* Query 2 */ UPDATE users SET age = 21 WHERE id = 1; COMMIT; /* in multiversion concurrencycontrol, or lock-based READ COMMITTED */ |
|
/* Query 1 */ SELECT * FROM users WHERE id = 1; COMMIT; /* lock-based REPEATABLE READ */ |
在这个例子中,事务2提交成功,因此他对id为1的行的修改就对其他事务可见了。但是事务1在此前已经从这行读到了另外一个“age”的值。在可序列化 (SERIALIZABLE)和可重复读(REPEATABLE READS)的隔离级别,数据库在第二次SELECT请求的时候应该返回事务2更新之前的值。在授权读(READ COMMITTED)和未授权读(READ UNCOMMITTED),返回的是更新之后的值,这个现象就是不可重复读(non-repeatable read)。
有两种策略可以避免不可重复读(non-repeatable read)。一个是要求事务2延迟到事务1提交或者回滚之后再执行。这种方式实现了T1, T2 的串行化调度。串行化调度可以支持可重复读(repeatable reads)。
另一种策略是多版本并发控制。为了得到更好的并发性能,允许事务2先提交。但因为事务1在事务2之前开始,事务1必须在其开始执行时间点的数据库的快照上面操作。当事务1最终提交时候,数据库会检查其结果是否等价于T1, T2串行调度。如果等价,则允许事务1提交,如果不等价,事务1需要回滚并抛出个串行化失败的错误。
使用基于锁的并发控制,在可重复读(REPEATABLE READS)的隔离级别中,ID=1的行会被锁住,在事务1提交或回滚前一直阻塞语句2的执行。在授权读(READ COMMITTED)的级别,语句1第二次执行,age已经被修改了。
在多版本并发控制机制下,可序列化(SERIALIZABLE)级别,两次SELECT语句读到的数据都是事务1开始的快照,因此返回同样的数据。但是,如果事务1试图UPDATE这行数据,事务1会被要求回滚并抛出一个串行化失败的错误。
在授权读(READ COMMITTED)隔离级别,每个语句读到的是语句执行前的快照,因此读到更新前后不同的值。在这种级别不会有串行化的错误(因为这种级别不要求串行化),事务1也不要求重试。
幻影读(phantom read)
在事务执行过程中,当两个完全相同的查询语句执行得到不同的结果集。这种现象称为“幻影读(phantom read)”
当事务没有获取范围锁的情况下执行SELECT ... WHERE操作可能会发生“幻影读(phantom read)”。
“幻影读(phantom read)”是不可重复读(Non-repeatable reads)的一种特殊场景:当事务1两次执行SELECT ... WHERE检索一定范围内数据的操作中间,事务2在这个表中创建了(如INSERT)了一行新数据,这条新数据正好满足事务1的“WHERE”子句。
事务 1 | 事务 2 |
---|---|
/* Query 1 */ SELECT * FROM users WHERE age BETWEEN 10 AND 30; |
|
/* Query 2 */ INSERT INTO users VALUES ( 3, 'Bob', 27 ); COMMIT; |
|
/* Query 1 */ SELECT * FROM users WHERE age BETWEEN 10 AND 30; |
需要指出的是事务1执行了两遍同样的查询语句。如果设了最高的隔离级别,两次会得到同样的结果集,这也正是可数据库在序列化(SERIALIZABLE)隔离级别上需要满足的。但是在较低的隔离级别上,第二次查询可能会得到不同的结果集。
在可序列化(SERIALIZABLE)隔离级别,查询语句1在age从10到30的记录上加锁,事务2只能阻塞直至事务1提交。在可重复读(REPEATABLE READ)级别,这个范围不会被锁定,允许记录插入,因此第二次执行语句1的结果中会包括新插入的行。
隔离级别、读现象和锁(Isolation Levels, Read Phenomena and Locks)
隔离级别vs读现象(Isolation Levels vs Read Phenomena)
隔离级别 | 脏读 | 不可重复读 | 幻影读 |
---|---|---|---|
未授权读 | 可能发生 | 可能发生 | 可能发生 |
授权读 | - | 可能发生 | 可能发生 |
可重复读 | - | - | 可能发生 |
可序列化 | - | - | - |
可序列化(Serializable)隔离级别不等同于可串行化(Serializable)。可串行化调度(Serializable)是避免以上三种现象的必要条件,但不是充分条件。
“可能发生”表示这个隔离级别会发生对应的现象,“-”表示不会发生。
隔离级别vs 锁持续时间(Isolation Levels vs Lock Duration)
在基于锁的并发控制中,隔离级别决定了锁的持有时间。"C"-表示锁会持续到事务提交。 "S" –表示锁持续到当前语句执行完毕。如果锁在语句执行完毕就释放则另外一个事务就可以在这个事务提交前修改锁定的数据,从而造成混乱。
隔离级别l | 写操作 | 读操作 | 范围操作 (...where...) |
---|---|---|---|
未授权读 | S | S | S |
授权读 | C | S | S |
可重复读 | C | C | S |
可序列化 | C | C | C |
参照
相关条目
- 原子性
- 一致性
- 持久性
- 锁
- 乐观并发控制
- 关系数据库
- 快照隔离
外部链接
- Oracle® Database Concepts, chapter 13 Data Concurrency and Consistency, Preventable Phenomena and Transaction Isolation Levels
- Oracle® Database SQL Reference, chapter 19 SQL Statements: SAVEPOINT to UPDATE, SET TRANSACTION
- in JDBC: Connection constant fields, Connection.getTransactionIsolation(), Connection.setTransactionIsolation(int)
- in Spring Framework: @Transactional, Isolation
Category:Data management Category:Transaction processing
为了转载内容的一致性、可追溯性和保证及时更新纠错,转载时请注明来自:http://www.cnblogs.com/douba/p/wikipedia_isolation.html。谢谢!
转载于:https://www.cnblogs.com/douba/p/wikipedia_isolation.html
【译】数据库事务隔离级别相关推荐
- 数据库事务隔离级别-- 脏读、幻读、不可重复读(清晰解释)
一.数据库事务隔离级别 数据库事务的隔离级别有4个,由低到高依次为Read uncommitted .Read committed .Repeatable read .Serializable ,这四 ...
- 数据库事务隔离级别+Spring 声明性事务隔离级别
数据库事务隔离级别 数据库提供了四种事务隔离级别, 不同的隔离级别采用不同的锁类开来实现. 在四种隔离级别中, Serializable的级别最高, Read Uncommited级别最低. 大多数数 ...
- mysql数据库事务隔离级别是_数据库事务隔离级别-MySQL为例 · Sean
在银行系统的存取款过程中,当遇到对一个账户并发存取的时候,系统该如何处理比较好.可能不少人会想到线程同步,然而在应用层使用同步会导致对象锁定,大大影响并发效率.此时,充分利用数据库的事务隔离机制可以很 ...
- 概述MySQL数据库---事务隔离级别
同一个应用程序中的多个事务或不同应用程序中的多个事务在同一个数据集上并发执行时, 可能会出现许多意外的问题,事务并发处理可能引起的问题可分为如下三种类型: 脏读(Drity Read): 已知有两个事 ...
- 数据库事务隔离级别及脏读、不可重复读、幻读的理解
开篇声明,由于两位大佬排版不够美观,然后又发现一些歧义,因此我集大佬之所长,精心整理并加以完善,可放心阅读. http://blog.csdn.net/yuxin6866/article/deta ...
- 数据库事务隔离级别有哪些?
数据库事务隔离级别: 1.Read Uncommitted(读未提交): 2.Read Committed(读已提交): 3.Repeatable Read(可重复读取): 4.Serializabl ...
- mysql数据库事务隔离级别演示
mysql数据库事务隔离级别演示 关键词: 一.基本概念 二.事务的四个特性(ACID) 三.事务的用法 3.1 相关命令 3.2 使用步骤 四.数据库的隔离级别 五.示例演示(每组事务结束手动com ...
- PG数据库事务隔离级别
Postgres数据库事务隔离级别介绍 0. What is Database Transaction? 数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列 ...
- 数据库事务隔离级别举例详解
目录 一.前言 1.1.4种事务隔离级别 1.2.3种读现象 二.举例说明 2.1.读未提交 2.2.读已提交 2.3.可重复读 2.4.串行化 一.前言 本文主要对4种事务隔离级别,具体举例说明各自 ...
- 数据库事务隔离级ORACLE数据库事务隔离级别介绍
本文系转载,原文地址:http://singo107.iteye.com/blog/1175084 数据库事务的隔离级别有4个,由低到高依次为Read uncommitted.Read committ ...
最新文章
- 谁是AI行业最受关注的人?未来图灵发布《AI明星企业家热搜榜》
- 嵌套中断共享资源问题及解决
- 张陈斌计算机控制工程,计算机控制讲稿--4.pdf
- Java并发编程实战~Balking模式
- 软件测试 学习之路 DOS常用命令
- TCP/IP Model: Layers Protocol | What is TCP IP Stack?
- Widows Live Writer
- 开课吧:Java开发常用技术基础部分有哪些?
- 关于多数据源(除自己数据库外,另一部分数据需通过接口调取第三方获取)的查询问题...
- vim编辑器初级(一)
- atitit 新特性与趋势管理的艺术 v2 s52.docx 1. lang语言系列 java node.js php 2 1.1. Atitit js es5 es6新特性 attilax总结
- xml笔记(马士兵)
- 7、线性方程组详细解法
- 【历史上的今天】2 月 20 日:Python 问世;Facebook 收购 WhatsApp;DEC 创始人出生
- 2017php最新版本,2017php受权验证系统2.6.8受权系统,真正完整可用,全新界面受权源码...
- 颈椎病及腰椎间盘突出病因病理
- 三国经典战役\三国合肥会战\三国孙权大战张辽\三国孙权一败张文远
- 如何清除掉“无法删除”的顽固文件
- 电脑扩展显示器启动后连接不上,需要重启才能连接
- [Java] 什么是IoC?什么是DI?它们的区别是什么?