设为首页 加入收藏

TOP

数据库的隔离级别(二)
2015-11-21 01:40:19 来源: 作者: 【 】 浏览:2
Tags:数据库 隔离 级别
?
事务隔离级别(transaction isolation levels):隔离级别就是对对事务并发控制的等级。ANSI/ ISO SQL将其分为串行化(SERIALIZABLE)、可重复读(REPEATABLE READ)、读已提交(READ COMMITED)、读未提交(READ UNCOMMITED)四个等级。为了实现隔离级别通常数据库采用锁(Lock)。一般在 编程的时候只需要设置隔离等级,至于具体采用什么锁则由 数据库来设置。首先介绍四种等级,然后举例解释后面三个等级(可重复读、读已提交、读未提交)中会出现的并发问题。
串行化(SERIALIZABLE):所有事务都一个接一个地串行执行,这样可以避免幻读(phantom reads)。对于基于锁来实现并发控制的数据库来说,串行化要求在执行范围查询(如选取年龄在10到30之间的用户)的时候,需要获取范围锁(range lock)。如果不是基于锁实现并发控制的数据库,则检查到有违反串行操作的事务时,需要滚回该事务。
可重复读(REPEATABLE READ):所有被Select获取的数据都不能被修改,这样就可以避免一个事务前后读取数据不一致的情况。但是却没有办法控制幻读,因为这个时候其他事务不能更改所选的数据,但是可以增加数据,因为前一个事务没有范围锁。
读已提交(READ COMMITED):被读取的数据可以被其他事务修改。这样就可能导致不可重复读。也就是说,事务的读取数据的时候获取读锁,但是读完之后立即释放(不需要等到事务结束),而写锁则是事务提交之后才释放。释放读锁之后,就可能被其他事物修改数据。该等级也是SQL Server默认的隔离等级。
读未提交(READ UNCOMMITED):这是最低的隔离等级,允许其他事务看到没有提交的数据。这种等级会导致脏读(Dirty Read)。
?
? ? ? ?例子:下面考察后面三种隔离等级对应的并发问题。假设有两个事务。事务1执行查询1,然后事务2执行查询2,然后提交,接下来事务1中的查询1再执行一次。查询基于以下表进行:
users
id name age
1 Joe 20
2 Jill 25
可重复读(幻读,phantom reads)
一个事务中先后各执行一次同一个查询,但是返回的结果集却不一样。发生这种情况是因为在执行Select操作的时候没有获取范围锁(Range Lock),导致其他事务仍然可以插入新的数据。

Transaction 1

Transaction 2

?

SELECT * FROM users

WHERE age BETWEEN 10 AND 30;

?

?

?

INSERT INTO users VALUES ( 3, 'Bob', 27 );

COMMIT;

?

SELECT * FROM users

WHERE age BETWEEN 10 AND 30;

?

?
注意transaction 1对同一个查询语句(Query 1)执行了两次。 如果采用更高级别的隔离等级(即串行化)的话,那么前后两次查询应该返回同样的结果集。但是在可重复读隔离等级中却前后两次结果集不一样。但是为什么叫做可重复读等级呢?那是因为该等级解决了下面的不可重复读问题。
读已提交(不可重复读,Non-repeatable reads)
在采用锁来实现并发控制的数据库 系统中,不可重复读是因为在执行Select操作的时候没有加读锁(read lock)。

Transaction 1

Transaction 2

?

SELECT * FROM users WHERE id = 1;

?

?

?

UPDATE users SET age = 21 WHERE id = 1;

COMMIT;

?

SELECT * FROM users WHERE id = 1;

?

?
在这个例子当中,Transaction 2提交成功,所以Transaction 1第二次将获取一个不同的age 值.在SERIALIZABLE和REPEATABLE READ隔离级别中,数据库应该返回同一个值。而在READ COMMITTED和READ UNCOMMITTED级别中数据库返回更新的值。这样就出现了不可重复读。
读未提交 (脏读,dirty reads)
如果一个事务2读取了另一个事务1修改的值,但是最后事务1滚回了,那么事务2就读取了一个脏数据,这也就是所谓的脏读。发生这种情况就是允许事务读取未提交的更新。

Transaction 1

Transaction 2

?

SELECT * FROM users WHERE id = 1;

?

?

?

UPDATE users SET age = 21 WHERE id = 1;

?

SELECT * FROM users WHERE id = 1;

?

?

RollBack

?
综上述,可以等到下面的表格:
?

隔离等级

脏读

不可重复读

幻读

读未提交

YES

YES

YES

读已提交

NO

YES

YES

可重复读

NO

NO

YES

串行化

NO

NO

NO

?

首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇SQL Server 动态行转列(参数化表.. 下一篇SQLDCL数据控制语言,用来定义访..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: