数据库事务隔离级别

一,事务的4个基本特征 

Atomic(原子性): 
事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要 
么全部成功,要么全部失败。 

Consistency(一致性): 
只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初 
状态。 

Isolation(隔离性): 
事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正 
确性和完整性。同时,并行事务的修改必须与其他并行事务的修改 
相互独立。 

Durability(持久性): 
事务结束后,事务处理的结果必须能够得到固化。 

在事务处理的ACID属性中,一致性是最基本的属性,其它的三个属性都为了保证一致性而存在的。

一致性,指的是数据处于一种有意义的状态,这种状态是语义上的而不是语法上的。最常见的例子是转帐。例如从帐户A转一笔钱到帐户B上,

如果帐户A上的钱减少了,而帐户B上的钱却没有增加,那么我们认为此时数据处于不一致的状态。

在数据库实现中,在同一个事务内部的一组操作必须全部执行成功(或者全部失败),这就是事务处理的原子性。

为了实现原子性,需要通过日志:将所有对数据的更新操作都写入日志,如果一个事务中的一部分操作已经成功,但以后的操作,

由于断电/系统崩溃/其它的软硬件错误而无法继续,则通过回溯日志,将已经执行成功的操作撤销,从而达到“全部操作失败”的目的。

最常见的场景是,数据库系统崩溃后重启,此时数据库处于不一致的状态,必须先执行一个crash recovery的过程:读取日志进行REDO

(重演将所有已经执行成功但尚未写入到磁盘的操作,保证持久性),再对所有到崩溃时尚未成功提交的事务进行UNDO(撤销所有执

行了一部分但尚未提交的操作,保证原子性)。crash recovery结束后,数据库恢复到一致性状态,可以继续被使用。

日志的管理和重演是数据库实现中最复杂的部分之一。如果涉及到并行处理和分布式系统(日志的复制和重演是数据库高可用性的基础),会比上述场景还要复杂得多。

但是,原子性并不能完全保证一致性。在多个事务并行进行的情况下,即使保证了每一个事务的原子性,仍然可能导致数据不一致的结果。例如,

事务1需要将100元转入帐号A:先读取帐号A的值,然后在这个值上加上100。但是,在这两个操作之间,另一个事务2修改了帐号A的值,为它

增加了100元。那么最后的结果应该是A增加了200元。但事实上, 事务1最终完成后,帐号A只增加了100元,因为事务2的修改结果被事务1覆盖掉了。

为了保证并发情况下的一致性,引入了隔离性,即保证每一个事务能够看到的数据总是一致的,就好象其它并发事务并不存在一样。用术语来说

,就是多个事务并发执行后的状态,和它们串行执行后的状态是等价的。怎样实现隔离性,已经有很多人回答过了,原则上无非是两种类型的锁:

一种是悲观锁,即当前事务将所有涉及操作的对象加锁,操作完成后释放给其它对象使用。为了尽可能提高性能,发明了各种粒度(数据库级/表级/行级……)/各种性质

(共享锁/排他锁/共享意向锁/排他意向锁/共享排他意向锁……)的锁。为了解决死锁问题,又发明了两阶段锁协议/死锁检测等一系列的技术。

一种是乐观锁,即不同的事务可以同时看到同一对象(一般是数据行)的不同历史版本。如果有两个事务同时修改了同一数据行,那么在较晚的事务提交时进行冲突检测。

实现也有两种,一种是通过日志UNDO的方式来获取数据行的历史版本,一种是简单地在内存中保存同一数据行的多个历史版本,通过时间戳来区分。

二,为什么需要对事务并发控制 

如果不对事务进行并发控制,我们看看数据库并发操作是会有那些异常情形

Lost update: 
两个事务都同时更新一行数据,但是第二个事务却中途失败退出, 
导致对数据的两个修改都失效了。

Dirty Reads: 
一个事务开始读取了某行数据,但是另外一个事务已经更新了此数 
据但没有能够及时提交。这是相当危险的,因为很可能所有的操作 
都被回滚。 

Non-repeatable Reads: 
一个事务对同一行数据重复读取两次,但是却得到了不同的结果。 

Second lost updates problem: 
无法重复读取的特例。有两个并发事务同时读取同一行数据,然后其 
中一个对它进行修改提交,而另一个也进行了修改提交。这就会造成 
第一次写操作失效。 

Phantom Reads: 
事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查 
询中未出现的数据(这里并不要求两次查询的SQL语句相同)。这是 
因为在两次查询过程中有另外一个事务插入数据造成的。 

三, 数据库的隔离级别 

为了兼顾并发效率和异常控制,在标准SQL规范中,定义了4个事务隔
离级别,(ORACLE和SQLSERER对标准隔离级别有不同的实现 )

Read Uncommitted: 
直译就是"读未提交",意思就是即使一个更新语句没有提交,但是别 
的事务可以读到这个改变.这是很不安全的. 

Read Committed: 
直译就是"读提交",意思就是语句提交以后即执行了COMMIT以后 
别的事务就能读到这个改变. 

Repeatable Read: 
直译就是"可以重复读",这是说在同一个事务里面先后执行同一个 
查询语句的时候,得到的结果是一样的. 

Serializable: 
直译就是"序列化",意思是说这个事务执行的时候不允许别的事务 
并发执行. 

四,隔离级别对并发的控制
 

下表是各隔离级别对各种异常的控制能力:

 

  LU DR NRR SLU PR
RU N Y Y Y Y
RC N N Y Y Y
RR N N N N Y
S N N N N N
时间: 2024-10-23 16:44:19

数据库事务隔离级别的相关文章

MSSQL与Oracle数据库事务隔离级别与锁机制对比_oracle

一,事务的4个基本特征 Atomic(原子性): 事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要 么全部成功,要么全部失败. Consistency(一致性): 只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初 状态. Isolation(隔离性): 事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正 确性和完整性.同时,并行事务的修改必须与其他并行事务的修改 相互独立. Durability(持久性): 事务结束后,事务处理的结果必须能够得到固化. 以上属于废话

MySQL数据库事务隔离级别介绍(Transaction Isolation Level)_Mysql

数据库隔离级别有四种,应用<高性能mysql>一书中的说明: 然后说说修改事务隔离级别的方法: 1.全局修改,修改mysql.ini配置文件,在最后加上 复制代码 代码如下:  #可选参数有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE. [mysqld] transaction-isolation = REPEATABLE-READ 这里全局默认是REPEATABLE-READ,其实MySQL本来默认也是这个级

Oracle数据库事务隔离级别概述

整理自Oracle 11g R2 官方文档 <concepts> 001 概述     Oracle数据库提供如下事务隔离级别:     ·已提交读隔离级别     ·可串行化隔离级别     ·只读隔离级别 002 读提交隔离级别2-1 概述     在(默认的)已提交读隔离级别中,事务中执行的每个查询,仅看到在查询 开始之前提交的数据--而不是事务开始之前提交的数据.这一隔离级别适合于几乎不可能发生事务冲突的数据库环境.     已提交读事务中的查询可以避免读取在查询过程中所提交的数据.例

深入分析MSSQL数据库中事务隔离级别和锁机制_MsSql

锁机制 NOLOCK和READPAST的区别. 1.       开启一个事务执行插入数据的操作. BEGIN TRAN t INSERT INTO Customer SELECT 'a','a' 2.       执行一条查询语句. SELECT * FROM Customer WITH (NOLOCK) 结果中显示"a"和"a".当1中事务回滚后,那么a将成为脏数据.(注:1中的事务未提交) .NOLOCK表明没有对数据表添加共享锁以阻止其它事务对数据表数据的修

MySQL的事务隔离级别和锁

MySQL的事务隔离级别:Read Uncommitted[读未提交数据]Read Committed[读已提交数据]Repeatable Read[可重读]Serializable[可串行化] 查看MySQL的事务隔离级别:默认.全局和会话事务隔离级别: SELECT @@tx_isolation SELECT @@global.tx_isolation; SELECT @@session.tx_isolation; mysql> select @@tx_isolation; +-------

mysql事务隔离级别与spring事务配置

问题描述 代码:voidfun(){Useruser=newUser();user.setId(1);user.setName("aaa");update(user);UsernewUser=select(1);//这里查询出的newUser的name还是更新前的值.}voidupdate(Useruser){//更新用户信息}Userselect(id){//根据id查询用户信息} 使用spring配置的事务的时候,上面方法fun.update被spring配置了事务propagat

深入分析MSSQL数据库中事务隔离级别和锁机制

锁机制 NOLOCK和READPAST的区别. 1.       开启一个事务执行插入数据的操作. BEGIN TRAN t INSERT INTO Customer SELECT 'a','a' 2.       执行一条查询语句. SELECT * FROM Customer WITH (NOLOCK) 结果中显示"a"和"a".当1中事务回滚后,那么a将成为脏数据.(注:1中的事务未提交) .NOLOCK表明没有对数据表添加共享锁以阻止其它事务对数据表数据的修

事务隔离级别小记

事务的四个属性:原子性(atomicity).一致性(consistency).隔离性(isolation)和持久性(durability). 1.原子性(Atomic)     最重要的原则,也是最容易理解的原则.被事务管理的所有方法,要么一起被提交,要么一起回滚. 2.一致性(Consistency)     事务在系统完整性中实施一致性,如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于新有效状态.如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态. 3.

MySQL InnoDB存储引擎的事务隔离级别

我们知道,在关系数据库标准中有四个事务隔离级别: 未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据 提交读(Read Committed):只能读取到已经提交的数据.Oracle等多数数据库默认都是该级别 可重复读(Repeated Read):可重复读.在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别.在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读 串行读(Serializable):完全串行化的读,每次读都需