技术开发 频道

SQL Server事务全攻略

  SQL Server事务全攻略(二)

  四 事务处理的隔离级别

  使用SET TRANSACTION ISOLATION LEVEL来控制由连接发出的所有语句的默认事务锁定行为

  从低到高依次是 READ UNCOMMITTED

  执行脏读或 0 级隔离锁定,这表示不发出共享锁,也不接受排它锁。当设置该选项时,可以对数据执行未提交读或脏读;在事务结束前可以更改数据内的数值,行也可以出现在数据集中或从数据集消失。该选项的作用与在事务内所有语句中的所有表上设置 NOLOCK 相同。这是四个隔离级别中限制最小的级别。

  举例,设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  c1
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

  五 事务处理嵌套的语法和对@@TRANCOUNT的影响

BEGIN TRAN @@TRANCOUNT+1 COMMIT TRAN @@TRANCOUNT-1 ROLLBACK TRAN
0
相关文章