转自http://www.cnblogs.com/Sun_Blue_Sky/articles/2139996.html
数据库的事务隔离级别
(TRANSACTION ISOLATION LEVEL)是一个数据库上很基本的一个概念。为什么会有事务隔离级别,SQL
Server上实现了哪些事务隔离级别?事务隔离级别的前提是一个多用户、多进程、多线程的并发系统,在这个系统中为了保证数据的一致性和完整性,我们引
入了事务隔离级别这个概念,对一个单用户、单线程的应用来说则不存在这个问题。
首先,我们来看一下高并发的系统中会存在哪些问题,为了便于理解我们以张三在招商银行的账号和存款为例。
一、准备工作:
1. 创建一个银行账号Table(只是为了说明问题,不考虑表的设计范式)
CREATE TABLE dbo.BankAccount
(
BankAccountId CHAR(16) NOT NULL, -- 银行账号
UserName NVARCHAR(32) NOT NULL, -- 用户
Balance DECIMAL(19, 2) NOT NULL, -- 余额
LastUpdate SMALLDATETIME NOT NULL
)
GO
2. 准备数据
INSERT INTO dbo.BankAccount
VALUES ('9555500100071120', N'张三', 10000.00, GETDATE()) -- 北京分行账号
INSERT INTO dbo.BankAccount
VALUES ('9555507551227787', N'张三', 20000.00, GETDATE()) -- 深圳分行账号
GO
3. 查看数据
SELECT * FROM dbo.BankAccount
二、应用场景
假设张三在招商银行开设了两个账号,一个是招商银行北京分行,一个是招商银行深圳分行,两个账号的余额分别是10,000和20,000。
1.
张三在网上做了一笔交易,交易额100,买方小王通过银行汇款100到张三的北京分行的账号(见下面左图),柜台操作人员向张三账号存入100(事务
一),然后系统些操作日志(假设需要10秒,WAITFOR DELAY
'00:00:10')正在此时张三在ATM查了一下账号上余额(事务二),发现已经是10100,于是回去准备发货,但是事务一在写操作日志时超时,这
是事务回滚,存款交易被取消,钱退给了小王,这样张三查到的账号余额事实上是事务一还没有提交的数据,导致张三错误的认为已经收到交易款项。
一个事务读到另外一个事务还没有提交的数据,我们称之为脏读。
解
决方法:把事务隔离级别调整到READ COMMITTED,即把右上图中的SET TRAN ISOLATION LEVEL READ
UNCOMMITTED更改成下图中的SET TRAN ISOLATION LEVEL READ
COMMITTED。这时我们重复上面的动作会发现事务二会一直等到事务一执行完毕再返回结果,因为此时事务以已经把自己的更改ROLLBACK了,所以
事务二可以返回正确的结果。
2. 张三先后两次查询某一账号的余额,在两次查询期间,小王完成了银行转账,导致两次的查询结果不同。
一个事务先后读取同一条记录,但两次读取的数据不同,我们称之为不可重复读。
解决方法:把事务隔离级别调整到REPEATABLE READ。在下图中使用SET TRAN ISOLATION LEVEL REPEATABLE READ。这时我们重复上面的动作会发现事务二会一直等到事务一执行完毕再返回结果。
3. 张三妻子先后两次查询张三招商银行所有账号的总余额,而在此期间张三在广州招商银行分行成功开设了一个账号,并存入5000,导致张三妻子两次查询的总余额不同,在此期间张三原有两个账号的余额均未发生改变。
一个事务先后读取一个范围的记录,但两次读取的纪录数不同,我们称之为幻象读。
解决方法:把事务隔离级别调整到SERIALIZABLE。在下图中使用SET TRAN ISOLATION LEVEL SERIALIZABLE。这时我们重复上面的动作会发现事务二会一直等到事务一执行完毕再返回结果。
三、总结
事务隔离级别是通过数据库的锁机制来控制的,在不同的应用场景需要应用不同的事务隔离级别,SQL Server默认的事务隔离级别是READ COMMITTED,默认的隔离级别,已经可以满足我们大部分应用的需求。
分享到:
相关推荐
数据库安全级别小别,加了锁更安全。MYSQL默认是有事物级别的
数据库隔离级别扫描.pdf
MySQL数据库隔离级别
数据库隔离级别的选择与实现
数据库隔离级别与脏读、幻读的深入解析
oracle 事务隔离级别 事务不同引发的状况: 脏读(Dirty reads) 一个事务读取另一个事务尚未提交的修改时,产生脏读 很多数据库允许脏读以避免排它锁的竞争。 不可重复读(Nonrepeatable reads) 同一查询在同一事务中...
数据库事务和隔离级别
数据库的隔离级别,数据库的隔离级别,数据库的隔离级别,数据库的隔离级别
近突然发现忘了数据库锁和数据库隔离级别,时常弄混它们之间的关系。为此特此写下此博客,以方便自己复习,同时也可以帮助博友。 数据库锁 数据库锁是事务T在对某个数据对象(例如表、记录等)操作之前,先向...
介绍数据库事务的四种隔离级别,比较不同隔离级别的区别和影响
GBase 8s隔离级别
GBase8s_隔离级别.docx
数据库隔离级别与Spring配置事务的联系及性能影响,以下是个人理解,如果有瑕疵请及时指正
有关JDBC事务 JTA事务 传播特性 隔离级别等等
数据库事务隔离级别.docx数据库事务隔离级别.docx数据库事务隔离级别.docx
查询:默认事务隔离级别 mysql> select @@tx_isolation;当前会话的默认事务隔离级别 mysql> select @@session.tx_isolation;当前会话的默认事务隔离级别 mysql> select @@global.tx_isolation;全局的事务隔离级别
数据库隔离级别是为了解决数据库并发访问过程中产生的各种数据安全问题. 事务的基本要素(ACID) 原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错...
DB2 inforcenter上的隔离级别介绍