none
SQL锁定问题 RRS feed

  • 问题

  • 在ORACLE中,可以如下使用锁,请问SQL SERVER能否实现

    1. 行级锁

    SELECT *
    FROM abc_class_tab a
    WHERE a.abc_class ='A'
    FOR UPDATE

    2. 如果正常选择,可以执行

    SELECT *
    FROM abc_class_tab a
    WHERE a.abc_class ='A'

    3. 如果再次执行行级锁,等待

    SELECT *
    FROM abc_class_tab a
    WHERE a.abc_class ='A'
    FOR UPDATE

    4. 可根据需要,看是否等待==> 例如下列语句,将不再等待,直接报错

    SELECT *
    FROM abc_class_tab a
    WHERE a.abc_class ='A'
    FOR UPDATE NOWAIT

    OAR-00054:resource busy and acquire with NOWAITspecified

     

    SQL SERVER是否能和ORACLE一样,做到如上锁定?

     

    2010年9月2日 5:35

答案

  • 参考下面的示例

     

    -- 创建示例数据
    USE tempdb;
    GO
    
    CREATE TABLE dbo.tb(
    	id int PRIMARY KEY
    );
    INSERT dbo.tb
    SELECT 1 UNION ALL
    SELECT 2
    ;
    GO
    
    -- 查询窗口 - 1
    -- 加锁
    -- SQL Server 的 SELECT 锁, 需要配合事务, 及特定的提示才能将锁保持
    BEGIN TRAN;
    
    SELECT * FROM dbo.tb WITH(UPDLOCK, ROWLOCK)
    	WHERE id = 1
    
    -- 显示锁信息
    EXEC sp_lock @@SPID
    GO
    --ROLLBACK TRAN
    --DROP TABLE dbo.tb
    
    
    
    
    -- 查询窗口 - 2
    -- 不同的记录, 可以加锁
    SELECT * FROM dbo.tb WITH(UPDLOCK)
    WHERE id = 2
    
    -- 可以普通查询
    SELECT * FROM dbo.tb
    WHERE id = 1
    GO
    
    -- 尝试锁定同一条记录需要等待
    SELECT * FROM dbo.tb WITH(UPDLOCK)
    WHERE id = 1
    
    
    
    2010年9月6日 4:42

全部回复

  • 可以使用

    with (nolock)

    with (rowlock)

    with(nowait) 等等。

    来实现记录锁

    具体查询MSDN with关键字。

     

     


    family as water
    2010年9月3日 2:31
  • with (nolock)

    with (rowlock)

    with(nowait)

    经测试,和我要的结果不一样

    Oracle里,For Update,只要没有提交,另外一个就等待

    SQL里,加了with(rowlock),没有提交,另外一个查询分析器里的同一段代码还是可以执行

    2010年9月4日 0:35
  • Sql works in different way, will not lock anything without running query.
    2010年9月4日 2:08
  • Oracle里,For Update,只要没有提交,另外一个就等待,而不管SQL有没有执行完毕。

    目的:

    修改之前锁定该行,其它程序要么等待,要么报行锁定

    流程如下:

    A锁定行  ==》 A进行操作 ==》A释放锁 ==》B。。。。

    2010年9月6日 1:54
  • You can submit it to sql server wish list.
    2010年9月6日 3:08
  • 参考下面的示例

     

    -- 创建示例数据
    USE tempdb;
    GO
    
    CREATE TABLE dbo.tb(
    	id int PRIMARY KEY
    );
    INSERT dbo.tb
    SELECT 1 UNION ALL
    SELECT 2
    ;
    GO
    
    -- 查询窗口 - 1
    -- 加锁
    -- SQL Server 的 SELECT 锁, 需要配合事务, 及特定的提示才能将锁保持
    BEGIN TRAN;
    
    SELECT * FROM dbo.tb WITH(UPDLOCK, ROWLOCK)
    	WHERE id = 1
    
    -- 显示锁信息
    EXEC sp_lock @@SPID
    GO
    --ROLLBACK TRAN
    --DROP TABLE dbo.tb
    
    
    
    
    -- 查询窗口 - 2
    -- 不同的记录, 可以加锁
    SELECT * FROM dbo.tb WITH(UPDLOCK)
    WHERE id = 2
    
    -- 可以普通查询
    SELECT * FROM dbo.tb
    WHERE id = 1
    GO
    
    -- 尝试锁定同一条记录需要等待
    SELECT * FROM dbo.tb WITH(UPDLOCK)
    WHERE id = 1
    
    
    
    2010年9月6日 4:42
  • 注意, 使用上述示例的时候

    先创建测试数据

    然后执行 查询窗口 - 1  的内容, 完成后, 新开一个查询窗口, 执行 查询窗口 - 2 的语句

    不要放在一个查询窗口中去执行

    2010年9月6日 4:44
  • 啰嗦一句, 一般尽量避免使用先锁定的悲观模式
    2010年9月6日 4:45
  • 经测试,您的方法可以实现我想要的功能。

     

    2010年9月6日 8:29