none
如何测试read committed下用的是共享锁行锁? RRS feed

  • 问题

  • 如何测试read committed下用的是共享锁行锁?并可以测试出在读取期间防止了其他事务对相关行的修改操作? thank you!
    2011年5月31日 10:24

答案

  • -- 参考这个示例
    USE tempdb;
    GO
    
    -- =================================
    -- 创建测试表
    CREATE TABLE dbo.tb(
    	id int IDENTITY
    		PRIMARY KEY,
    	name sysname
    );
    INSERT dbo.tb
    SELECT
    	name
    FROM sysobjects
    ;
    GO
    
    -- =================================
    -- 测试共享锁的连接窗口1 
    -- SELECT 共享锁
    SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
    
    -- 通过事务和 HOLDLOCK 锁定提示将共享锁保持到事务结束,以便在另一个中测试这个锁
     --否则查询完成后,共享锁就没了,没办法测试
    BEGIN TRAN;
    SELECT * FROM dbo.tb WITH(HOLDLOCK)	
    WHERE id = 1
    ;
    
    -- 显示当前进程的锁信息
    EXEC sp_lock @@SPID;
    
    
    
    2011年6月1日 2:31
  • USE tempdb;
    GO
    -- =================================
    -- 测试共享锁的连接窗口2
    SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
    
    -- 共享锁不冲突,所以应该能够查询
    SELECT * FROM dbo.tb WITH(HOLDLOCK)	
    WHERE id = 1
    ;
    
    -- 应该能够 UPDATE 其他记录
    UPDATE dbo.tb SET
    	name = N'aa'
    WHERE id = 2
    ;
    
    -- 显示一个提示,知道更新结束
    RAISERROR(
    	N'update id = 2 completed',
    	10, 1
    ) WITH NOWAIT;
    
    -- 应该不能 UPDATE 其锁定的记录
    UPDATE dbo.tb SET
    	name = N'aa'
    WHERE id = 1
    ;
    RAISERROR(
    	N'update id = 1 completed',
    	10, 1
    ) WITH NOWAIT;
    
    
    2011年6月1日 2:32
  • 可以在查询分析器或者 managent studio 查询窗口中来使用这个示例

    首先开启一个查询窗口,执行第一部分的 T-SQL, 这部分 T-SQL 创建一个示例表, 并且通过 SELECT 在表的 id = 1 的记录上下共享锁

    然后再建一个查询窗口, 连接到同样的示例,执行第二部分 T-SQL, 这个部分显示 共享锁如何 阻塞对id = 1 的记录做更新(其他 id 的记录不受影响)

     

    在第一部分的 T-SQL 执行后,会输出加锁的信息,应该可以看到类似这样一个结果(id 什么的会与我的不一样),最后一条记录显示的是在指定的 Key 上面有一个共享锁,Key 是唯一的,所以是一个行级锁

    spid   dbid   ObjId       IndId  Type Resource                         Mode     Status
    ------ ------ ----------- ------ ---- -------------------------------- -------- ------
    51     2      69575286    1      PAG  1:126                            IS       GRANT
    51     2      69575286    0      TAB                                   IS       GRANT
    51     1      1131151075  0      TAB                                   IS       GRANT
    51     2      69575286    1      KEY  (8194443284a0)                   S        GRANT

    2011年6月1日 2:36

全部回复

  • 给个定义给你,看明白了就知道如何测试这个了。

    共享 (S) 锁允许并发事务读取 (SELECT) 一个资源。资源上存在共享 (S) 锁时,任何其它事务都不能 修改数据一旦已经读取数据,便立即释放资源上的共享 (S) 锁,除非将事务隔离级别设置为可重复读或 更高级别,或者在事务生存周期内用锁定提示保留共享 (S) 锁。

    注意黑体部分。这个可以用sql 使用 holdlock来保持这个共享锁 以便测试更新。


    family as water
    2011年5月31日 13:15
  • -- 参考这个示例
    USE tempdb;
    GO
    
    -- =================================
    -- 创建测试表
    CREATE TABLE dbo.tb(
    	id int IDENTITY
    		PRIMARY KEY,
    	name sysname
    );
    INSERT dbo.tb
    SELECT
    	name
    FROM sysobjects
    ;
    GO
    
    -- =================================
    -- 测试共享锁的连接窗口1 
    -- SELECT 共享锁
    SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
    
    -- 通过事务和 HOLDLOCK 锁定提示将共享锁保持到事务结束,以便在另一个中测试这个锁
     --否则查询完成后,共享锁就没了,没办法测试
    BEGIN TRAN;
    SELECT * FROM dbo.tb WITH(HOLDLOCK)	
    WHERE id = 1
    ;
    
    -- 显示当前进程的锁信息
    EXEC sp_lock @@SPID;
    
    
    
    2011年6月1日 2:31
  • USE tempdb;
    GO
    -- =================================
    -- 测试共享锁的连接窗口2
    SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
    
    -- 共享锁不冲突,所以应该能够查询
    SELECT * FROM dbo.tb WITH(HOLDLOCK)	
    WHERE id = 1
    ;
    
    -- 应该能够 UPDATE 其他记录
    UPDATE dbo.tb SET
    	name = N'aa'
    WHERE id = 2
    ;
    
    -- 显示一个提示,知道更新结束
    RAISERROR(
    	N'update id = 2 completed',
    	10, 1
    ) WITH NOWAIT;
    
    -- 应该不能 UPDATE 其锁定的记录
    UPDATE dbo.tb SET
    	name = N'aa'
    WHERE id = 1
    ;
    RAISERROR(
    	N'update id = 1 completed',
    	10, 1
    ) WITH NOWAIT;
    
    
    2011年6月1日 2:32
  • 可以在查询分析器或者 managent studio 查询窗口中来使用这个示例

    首先开启一个查询窗口,执行第一部分的 T-SQL, 这部分 T-SQL 创建一个示例表, 并且通过 SELECT 在表的 id = 1 的记录上下共享锁

    然后再建一个查询窗口, 连接到同样的示例,执行第二部分 T-SQL, 这个部分显示 共享锁如何 阻塞对id = 1 的记录做更新(其他 id 的记录不受影响)

     

    在第一部分的 T-SQL 执行后,会输出加锁的信息,应该可以看到类似这样一个结果(id 什么的会与我的不一样),最后一条记录显示的是在指定的 Key 上面有一个共享锁,Key 是唯一的,所以是一个行级锁

    spid   dbid   ObjId       IndId  Type Resource                         Mode     Status
    ------ ------ ----------- ------ ---- -------------------------------- -------- ------
    51     2      69575286    1      PAG  1:126                            IS       GRANT
    51     2      69575286    0      TAB                                   IS       GRANT
    51     1      1131151075  0      TAB                                   IS       GRANT
    51     2      69575286    1      KEY  (8194443284a0)                   S        GRANT

    2011年6月1日 2:36