sql – 采取独占锁的正确方法

前端之家收集整理的这篇文章主要介绍了sql – 采取独占锁的正确方法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在编写一个程序来协调实时数据库上的有关交易.我正在做的工作不能作为一个集合操作完成,所以我使用两个嵌套游标.

我需要在每个客户端协调时对事务表进行独占锁定,但我想释放锁定并让其他人在我处理的每个客户端之间运行查询.

我希望在行级别而不是表级别上进行独占锁定,但是what I have read so far说如果其他事务在READCOMMITED隔离级别(对我而言)运行,我无法处理(XLOCK,ROWLOCK,HOLDLOCK) .

我是否正确地采用了表级别的独占锁,并且在Server 2008 R2中是否有任何方法可以使行级别的独占锁以我想要的方式工作而无需修改数据库上运行的其他查询

declare client_cursor cursor local forward_only for 
     select distinct CLIENT_GUID from trnHistory
open client_cursor

declare @ClientGuid uniqueidentifier
declare @TransGuid uniqueidentifier

fetch next from client_cursor into @ClientGuid
WHILE (@@FETCH_STATUS <> -1)
BEGIN
    IF (@@FETCH_STATUS <> -2)
    BEGIN
        begin tran

        declare @temp int

        --The following row will not work if the other connections are running READCOMMITED isolation level
        --select @temp = 1 
    --from trnHistory with (XLOCK,HOLDLOCK) 
    --left join trnCB with (XLOCK,HOLDLOCK) on trnHistory.TRANS_GUID = trnCB.TRANS_GUID
    --left join trnClients with (XLOCK,HOLDLOCK) on trnHistory.TRANS_GUID = trnClients.TRANS_GUID
    --(Snip) --Other tables that will be "touched" during the reconcile
    --where trnHistory.CLIENT_GUID = @ClientGuid

        --Works allways but locks whole table.
    select top 1 @temp = 1 from trnHistory with (XLOCK,TABLOCK) 
    select top 1 @temp = 1 from trnCB with (XLOCK,TABLOCK)
    select top 1 @temp = 1 from trnClients with (XLOCK,TABLOCK)
    --(Snip) --Other tables that will be "touched" during the reconcile

        declare trans_cursor cursor local forward_only for 
                select TRANS_GUID from trnHistory where CLIENT_GUID = @ClientGuid order by TRANS_NUMBER
        open trans_cursor

        fetch next from trans_cursor into @TransGuid
        WHILE (@@FETCH_STATUS <> -1)
        BEGIN
            IF (@@FETCH_STATUS <> -2)
            BEGIN

                --Do Work here

            END
            fetch next from trans_cursor into @TransGuid
        END

        close trans_cursor
        deallocate trans_cursor

            --commit the transaction and release the lock,this allows other 
            -- connections to get a few queries in while it is safe to read.
        commit tran
    END

    fetch next from client_cursor into @ClientGuid
END 

close client_cursor
deallocate client_cursor

解决方法

如果你只是担心其他读者,那么你不应该需要独占锁,模式
Begin Transaction

  Make Data Inconsistent

  Make Data Consistent

Commit Transaction

应该没事.将看到不一致数据的唯一会话是那些使用nolock或Read Uncommitted的会话,或那些期望在不使用Repeatable Rows或Serializable的情况下进行多次一致读取的会话.

在回答这个问题时,我认为采取独家锁定的正确方法是安排事情,以便引擎为您完成.

猜你在找的MsSQL相关文章