各位数据库高手能否给出四种隔离级别的使用时机,现在对这个咚咚还不是很明白。

foxgong 2003-11-19 10:31:41
isolation level serializable
isolation level read-uncommitted
isolation level read committed
isolation level repeatable read

事务中使用这些隔离级别需要注意些什么?
在什么时机适合使用这些隔离级别?
请高手给出建议,有出处最好,在哪本书上有详细说明,也可告知。谢谢了!
...全文
68 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
happydreamer 2003-11-20
  • 打赏
  • 举报
回复
举例

设table1(A,B,C)
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3

新建两个连接
在第一个连接中执行以下语句
select * from table1
begin tran
update table1 set c='c'
select * from table1
waitfor delay '00:00:10' --等待10秒
rollback tran
select * from table1

在第二个连接中执行以下语句
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
print '脏读'
select * from table1
if @@rowcount>0
begin
waitfor delay '00:00:10'
print '不重复读'
select * from table1
end

第二个连接的结果

脏读
A B C
a1 b1 c
a2 b2 c
a3 b3 c

'不重复读'
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3


READ COMMITTED

指定在读取数据时控制共享锁以避免脏读,但数据可在事务结束前更改,从而产生不可重复读取或幻像数据。该选项是 SQL Server 的默认值。

在第一个连接中执行以下语句
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
begin tran
print '初始'
select * from table1
waitfor delay '00:00:10' --等待10秒
print '不重复读'
select * from table1
rollback tran


在第二个连接中执行以下语句
SET TRANSACTION ISOLATION LEVEL READ COMMITTED

update table1 set c='c'

第一个连接的结果

初始
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3

不重复读
A B C
a1 b1 c
a2 b2 c
a3 b3 c

REPEATABLE READ

锁定查询中使用的所有数据以防止其他用户更新数据,但是其他用户可以将新的幻像行插入数据集,且幻像行包括在当前事务的后续读取中。因为并发低于默认隔离级别,所以应只在必要时才使用该选项。

在第一个连接中执行以下语句
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
begin tran
print '初始'
select * from table1
waitfor delay '00:00:10' --等待10秒
print '幻像读'
select * from table1
rollback tran

在第二个连接中执行以下语句
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
insert table1 select 'a4','b4','c4'

第一个连接的结果

初始
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3

幻像读
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3
a4 b4 c4


SERIALIZABLE

在数据集上放置一个范围锁,以防止其他用户在事务完成之前更新数据集或将行插入数据集内。这是四个隔离级别中限制最大的级别。因为并发级别较低,所以应只在必要时才使用该选项。该选项的作用与在事务内所有 SELECT 语句中的所有表上设置 HOLDLOCK 相同。

在第一个连接中执行以下语句
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
begin tran
print '初始'
select * from table1
waitfor delay '00:00:10' --等待10秒
print '没有变化'
select * from table1
rollback tran


在第二个连接中执行以下语句
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
insert table1 select 'a4','b4','c4'

第一个连接的结果

初始
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3

没有变化
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3

zjcxc 元老 2003-11-20
  • 打赏
  • 举报
回复
呵呵,已经够详细了.
youngby 2003-11-19
  • 打赏
  • 举报
回复
use pubs
go

select * from employee where job_id=13 and minit='m'
go


begin tran
update employee
set fname='loveyou'
where job_id=13 and minit='M'---事物不提交


---以下在另一个连接中执行-------------
set transaction isolation level read uncommitted --读为未提交
go
select * from Employee
where job_id=13 and minit='M'--则此时的数据fname被该为了loveyou,为脏读

--重新设置事物的隔离级别--------------

set transaction isolation level read committed --读为提交
go
select * from Employee
where job_id=13 and minit='M'--则此时的数据fname被为原来的数值
youngby 2003-11-19
  • 打赏
  • 举报
回复
begin tran
update employee
set fname='loveyou'
where job_id=13 and minit='M'---事物不提交


---以下在另一个连接中执行-------------
set transaction isolation level read uncommitted --读为未提交
go
select * from Employee
where job_id=13 and minit='M'--则此时的数据fname被该为了loveyou,为脏读

--重新设置事物的隔离级别--------------

set transaction isolation level read committed --读为提交
go
select * from Employee
where job_id=13 and minit='M'--则此时的数据fname被为原来的数值
pengdali 2003-11-19
  • 打赏
  • 举报
回复
举个例:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

是为了防止在事务没有完成的时候另一用户,访问事务内,未提交的数据
create table Table1 (a int)
go
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
begin tran
insert table1 values(1) ----这句在事物没有commit前,被另一个用户
----访问是错误的,应为下面有可能会出错

insert table1 values('aaa') ----这句由于类型不一样将报错
----设置了SERIALIZABLE的话就不会发生脏读
commit tran

select * from table1

34,663

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧