Sql Server隔离级别(1)

数据库是一个并发操做的环境,就像多线程同样,这样在高并发的状况下回出现一些问题。html

假设咱们有一张表Account,表结构和数据以下所示数据库

AccountName Balance
jo 100
fo 200

 

 

 

假设咱们有两个事事务(T1,T2)多线程

脏读:当一个事务容许读取另一个事务修改但未提交的数据时,就可能发生脏读(dirty reads)。并发

(1)T1更新jo的余额:高并发

UPDATE Account SET Balance=500 WHERE AccountName='jo'

 

(2)T2选出jo的余额:spa

SELECT Balance FROM Account WHERE AccountName='jo'

(3)T1回滚(rollback)。线程

此时在(2)中已经选出了500这个值,尽管最后T1的回滚让jo的余额保持100没有改变,这种状况就是脏读。code

 

不可重复读:在一次事务中,当一行数据获取两遍获得不一样的结果表示发生了"不可重复读(non-repeatable read)"。htm

(1)T2选出jo的余额:对象

SELECT Balance FROM Account WHERE AccountName='jo'

 (2)T1中更新jo的余额而且提交(commit)。

UPDATE Account SET Balance=500 WHERE AccountName='jo'
Commit Tran

(3)T2再次选出jo的余额

SELECT Balance FROM Account WHERE AccountName='jo'

此时在(1)中选出的余额是100,在(3)中选出的余额是500,在同一个事务T2中两个Select获得了不同的数据。

 

幻读:在事务执行过程当中,当两个彻底相同的查询语句执行获得不一样的结果集。这种现象称为“幻读(phantom read)”

(1)T2选择金额大于100的帐户余额

SELECT Balance FROM Account WHERE Balance>100

(2)T1插入新的余额大于100的帐户

INSERT INTO Account (AccountName,Balance) VALUES ('ho',300)

(3)T2中再次选择金额大于100的帐户

SELECT Balance FROM Account WHERE Balance>100

此时(1)读出了一条数据,(2)读出了两条数据,同一个查询的在同一个事务中的两次读取获得了不一样的数量的结果集,这种现象就是幻读。

 

为了处理以上并发问题,有了并发控制的概念。简单来讲就是一个事务在执行的时候,经过对正在访问的资源加锁来阻塞其余事务对资源的操做。

不一样的加锁方式对应不一样的隔离级别,用来针对不一样的并发问题。

READ UNCOMMITTED 

事务执行期间,对任何操做不加锁。意味着能够读取其余事务未提交的更新。这个隔离级别下以上的并发问题都有可能发生。

READ COMMITTED 

事务执行期间,对写操做加锁。意味着当前将要写入的数据加了写锁,阻塞其余事务读取或者更改加锁数据,直到事务结束。

这个隔离级别能够防止其余的事务脏读,由于其余的事务对加锁数据的读写操做都被当前事务阻塞了。不过因为当前事务没有加读锁,因此当前事务会发生不可重复读。

REPEATABLE READ

事务执行期间,对读,写操做加锁。意味着当前事务写入和读取的数据其余的事务都没法访问,知道当前事务结束(回滚,或者提交),当前事务不会发生不可重复读,不过因为当前读取的数据范围没有加锁,其余的事务能够插入知足当前事务读取范围过滤条件的数据;或者更新当前事务读取范围外的数据,已使其知足当前事务的读取范围过滤条件。这样就会形成幻读。

SERIALIZABLE

可序列化或者叫可串行化,按照字面意思,是事务只能一个接着一个的执行。

实际的实现方式是经过加读锁,写锁和范围锁来保证事务执行的串行化。意味着在当前事务的执行过程当中,会阻塞其余的涉及当前事务相关数据及数据范围的事务。

 

本文只是一个简单的介绍,要彻底的理解隔离级别,而且推断出事务在不一样隔离级别下会有什么样的不一样就要深刻的了解SQL Server在不一样隔离级别下对不一样对象的锁定,以及不一样的锁之间是如何交互的,这些方面的问题推荐下面这篇博客:

http://www.cnblogs.com/RicCC/archive/2010/03/05/transaction-lock-isolation-level.html

相关文章
相关标签/搜索