首先执行begin tran
select * from school with(xlock)
在事物内对表school申请排它锁
begin tran
select * from school 又一个事务对表school执行查询,按道理来说执行查询要对查询的数据申请共享锁,那么此查询会被阻塞(因为两个事务都还没有提交也没有回滚),但是第二个事务并没有造成阻塞,查询顺利执行,难道第二个事务的查询没有申请共享锁?另外数据库没有建立任何索引,也没有开启任何快照

解决方案 »

  1.   

    begin tran
    select * from school with(xlock,HOLDLOCK)这样就会保持锁了
      

  2.   

    1 如何锁一个表的某一行A 连接中执行SET TRANSACTION ISOLATION LEVEL REPEATABLE READbegin transelect * from tablename with (rowlock) where id=3waitfor delay '00:00:05'commit tranB连接中如果执行update tablename set colname='10' where id=3 --则要等待5秒update tablename set colname='10' where id<>3 --可立即执行2 锁定数据库的一个表SELECT * FROM table WITH (HOLDLOCK) 
    注意: 锁定数据库的一个表的区别SELECT * FROM table WITH (HOLDLOCK) 
    其他事务可以读取表,但不能更新删除SELECT * FROM table WITH (TABLOCKX) 
    其他事务不能读取表,更新和删除
      

  3.   

    这个问题以前讨论过,有点奇怪:
    一个新建的表(从未被 update 过),如果使用 select 语句查询,select 语句将不会请求 S 锁。
    但是,一旦在此表上发生过阻塞后,SQL SERVER 像想通了一样,以后查询此表的 select 语句将会请求 S 锁。
    例如,-- 新建一表
    create table tb (id int identity, c char(10));
    go
    insert into tb(c) 
    select 'a' union all select 'b';
    go-- 会话一中执行 select 查询,不会请求 s 行锁
    select * from tb;-- 会话二中
    begin tran
     update tb set c='x';-- 会话一中执行 select 查询,产生阻塞
    select * from tb;-- 会话二中回滚事务,释放锁
    rollback tran;-- 再在 会话一中执行 select 查询,将会请求 s 行锁
    select * from tb;
    又但是,如果这个表创建在 TEMPDB 数据库上,查询此表的 select 语句始终会请求 S 锁。不知道是微软为性能故意而为,还是其他(SQL SERVER 2005 和 2008 上使用 SQL Profiler 测试)
      

  4.   

    为啥我的Update执行时没阻塞呢?
    另外想问下在SQL Profiler 怎么查看申请锁的类型
      

  5.   

    总结到了一点:select * from school 
    在申请页锁或者表锁时会阻塞,或者如2楼所说把X锁加在表上或页上也会阻塞
    反正把X锁加在行上,或者申请的锁是行锁都不会阻塞
      

  6.   

    sql server读取是不是加锁,和你的数据库版本和设置有关
    2000或以前版本,默认是加锁的
    2005以上版本,要看你的事务隔离机制是设置的快照还是别的.快照的时候,是不加所的
      

  7.   

    确定没有使用 SNAPSHOT 或 READ COMMITTED SNAPSHOT 事务隔离级别。#5 所做的测试,在我的 SQL Server 上总是成立。
      

  8.   

    参考http://topic.csdn.net/u/20090829/12/7d49a4fd-ba2c-4c5c-8c29-52cd76de1841.html
    及里面的链接。
      

  9.   

    原因同这个相同:
    http://www.cnblogs.com/nzperfect/archive/2010/02/25/1673667.html
      

  10.   

    确信没快照,因为我还有张叫people的表,这张表我试了神奇的发现如你所说无论怎么查他都会申请S锁,这张表是很早以前建的,而这里出问题的school表是我昨天建的,难道SQL server的优化还要有个时间限制.....汗!
      

  11.   


    加菲大哥我知道为啥结果和你不一样了,请看rollback tran后面的注释,这问题太复杂了....-- 新建一表
    create table tb (id int identity, c char(10));
    go
    insert into tb(c) 
    select 'a' union all select 'b';
    go-- 会话一中执行 select 查询,不会请求 s 行锁
    select * from tb;-- 会话二中
    begin tran
     update tb set c='x';-- 会话一中执行 select 查询,产生阻塞
    select * from tb;-- 会话二中回滚事务,释放锁
    rollback tran;--这儿貌似用commit,以后查询还是不会申请S锁,但是该为rollback以后就会申请S锁了-- 再在 会话一中执行 select 查询,将会请求 s 行锁
    select * from tb;