共享锁
在第一个连接中执行以下语句
begin tran
   select * from table1 holdlock -holdlock人为加锁
   where B='b2' 
   waitfor delay '00:00:30'  --等待30秒
commit tran在第二个连接中执行以下语句
begin tran
   select A,C from table1
   where B='b2' 
   update table1
   set A='aa'
   where B='b2'   
commit tran若同时执行上述两个语句,则第二个连接中的select查询可以执行
而update必须等待第一个连接中的共享锁结束后才能执行 即要等待30秒事务代码 例:create table Table1 (a int)
go
begin tran
  insert table1 values(1)               ----这句是对的
  insert table1 values('aaa')           ----这句由于类型不一样将报错
commit transelect * from table1         ------结果是两句都没插入!应为他们是一个事务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 transelect * from table1
SET TRANSACTION ISOLATION LEVEL
控制由连接发出的所有 Microsoft® SQL Server™ SELECT 语句的默认事务锁定行为参数
READ COMMITTED指定在读取数据时控制共享锁以避免脏读,但数据可在事务结束前更改,从而产生不可重复读取或幻像数据。该选项是 SQL Server 的默认值。READ UNCOMMITTED执行脏读或 0 级隔离锁定,这表示不发出共享锁,也不接受排它锁。当设置该选项时,可以对数据执行未提交读或脏读;在事务结束前可以更改数据内的数值,行也可以出现在数据集中或从数据集消失。该选项的作用与在事务内所有语句中的所有表上设置 NOLOCK 相同。这是四个隔离级别中限制最小的级别。REPEATABLE READ锁定查询中使用的所有数据以防止其他用户更新数据,但是其他用户可以将新的幻像行插入数据集,且幻像行包括在当前事务的后续读取中。因为并发低于默认隔离级别,所以应只在必要时才使用该选项。SERIALIZABLE在数据集上放置一个范围锁,以防止其他用户在事务完成之前更新数据集或将行插入数据集内。这是四个隔离级别中限制最大的级别。因为并发级别较低,所以应只在必要时才使用该选项。该选项的作用与在事务内所有 SELECT 语句中的所有表上设置 HOLDLOCK 相同。

解决方案 »

  1.   

    用强制表级锁(holdlock)会使并发性能下降,MS也不推荐这样用,
    你可以这样会好些。
    begin tran
       UPDATE TABLE1 SET ID=1 WHERE 1=2  --加一个表级锁在TABLE1
       select * from table1
       where B='b2' 
    commit tran
      

  2.   

    是为了防止在事务没有完成的时候另一用户,访问事务内,未提交的数据
    create table Table1 (a int)
    go
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    begin tran
      insert table1 values(1)               ----这句在事物没有commit前,被另一个用户
                                            ----访问是错误的,应为下面有可能会出错  insert table1 values('aaa')           ----这句由于类型不一样将报错
                                            ----设置了SERIALIZABLE的话就不会发生脏读
    commit transelect * from table1
      

  3.   

    实际上begin tran commit就可以了,你不需要为sql考虑那么多