我正在编写一个程序来协调实时数据库上的有关交易.我正在做的工作不能作为一个集合操作完成,所以我使用两个嵌套游标.
我需要在每个客户端协调时对事务表进行独占锁定,但我想释放锁定并让其他人在我处理的每个客户端之间运行查询.
我希望在行级别而不是表级别上进行独占锁定,但是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的情况下进行多次一致读取的会话.
在回答这个问题时,我认为采取独家锁定的正确方法是安排事情,以便引擎为您完成.