触发期间SQL Server 2008锁定表

时间:2012-06-19 09:07:56

标签: sql-server-2008 triggers transactions locking

情况如下。我们有两个数据库,我们使用我们要复制的表CPT foreach表创建了一个异步复制系统。

所以每次都有一个表上的操作,例如(BATCH_COUNT),一个触发器被调用,我们写入CPT表(BATCH_COUNT_CPT)我们做了什么操作哪排。服务读取该表并执行所请求的操作。

为了避免在表CPT中多次插入,触发器检查是否已经有UPDATE未处理,因此它没有插入新的更新,或者如果删除了,它删除该行的所有操作并插入删除。

ALTER TRIGGER [dbo].[BATCH_COUNT_CPT_TRIGGER]
  ON  [dbo].[BATCH_COUNT]
  AFTER INSERT,UPDATE,DELETE
AS
BEGIN
     -- SET NOCOUNT ON added to prevent extra result sets from
     -- interfering with SELECT statements.
     SET NOCOUNT ON;

   -- Insert statements for trigger here

   if((select UPPER(suser_name())) <> UPPER('XXXXXX\UEWIcptValService'))
   begin

--------------------------DELETE----------------------------------------
           if ((select count(*) from inserted) = 0 and (select count(*) from deleted) <> 0)
           begin
                 DECLARE @CptId uniqueidentifier;
                 DECLARE deleteCursor CURSOR FAST_FORWARD FOR
                 SELECT CPT_ID FROM deleted

                 OPEN deleteCursor

                 FETCH NEXT FROM deleteCursor INTO @CptId

                 WHILE @@FETCH_STATUS = 0
                 BEGIN
                       if((select count(CPT_ID) from [BATCH_COUNT_CPT] where CPT_ID = @CptId and OPERATION = 'INSERT') <> 0)
                       Begin
                             DELETE FROM [NEWDOCS].[dbo].[BATCH_COUNT_CPT] WHERE CPT_ID = @CptId
                       End
                       ELSE
                             if((select count(CPT_ID) from [BATCH_COUNT_CPT] where CPT_ID = @CptId and OPERATION = 'UPDATE') <> 0)
                             Begin
                                   DELETE FROM [NEWDOCS].[dbo].[BATCH_COUNT_CPT] WHERE CPT_ID = @CptId
                                   INSERT INTO NEWDOCS.dbo.BATCH_COUNT_CPT (CPT_ID,OPERATION,[Date],[Skip]) VALUES (@CptId, 'DELETE',GetDate(),0)
                             End
                             ELSE
                                   if((select count(CPT_ID) from [BATCH_COUNT_CPT] where CPT_ID = @CptId and OPERATION = 'DELETE') = 0)
                                   Begin
                                         INSERT INTO NEWDOCS.dbo.BATCH_COUNT_CPT (CPT_ID,OPERATION,[Date],[Skip])  VALUES (@CptId, 'DELETE',GetDate(),0)
                                   End
                   FETCH NEXT FROM deleteCursor INTO @CptId
                 END

                 CLOSE deleteCursor
                 DEALLOCATE deleteCursor

           end
--------------------------END DELETE----------------------------------------



--------------------------UPDATE--------------------------------------------
           if ((select count(*) from inserted) <> 0 and (select count(*)from deleted) <> 0)
           begin

                 --DECLARE @CptId uniqueidentifier;
                 DECLARE insertCursor CURSOR FAST_FORWARD FOR
                 SELECT CPT_ID FROM inserted


                 OPEN insertCursor

                 FETCH NEXT FROM insertCursor INTO @CptId

                 WHILE @@FETCH_STATUS = 0
                 BEGIN
                   ---
                       if((select count(CPT_ID) from [BATCH_COUNT_CPT] where CPT_ID = @CptId and (OPERATION = 'INSERT' or OPERATION = 'UPDATE')) = 0)
                             Begin
                                   INSERT INTO NEWDOCS.dbo.BATCH_COUNT_CPT (CPT_ID,OPERATION,[Date],[Skip])  VALUES (@CptId, 'UPDATE',GetDate(),0)
                             End
                   ---
                   FETCH NEXT FROM insertCursor INTO @CptId
                 END

                 CLOSE insertCursor
                 DEALLOCATE insertCursor

           end
--------------------------END UPDATE----------------------------------------



--------------------------INSERT--------------------------------------------
           if ((select count(*) from inserted) <> 0 and (select count(*)from deleted) = 0)
           begin
                 INSERT INTO NEWDOCS.dbo.BATCH_COUNT_CPT (CPT_ID,OPERATION,[Date],[Skip])  SELECT CPT_ID,'INSERT',GetDate(),0 FROM INSERTED;
           end
--------------------------END INSERT----------------------------------------
     end
END

所以问题是在触发器执行期间表BATCH_COUNT_CPT没有被锁定。如果服务读取并删除它,可能会导致问题,并且某些操作将丢失。在执行整个触发器期间,我不知道如何在CPT表上执行锁定。

我认为

 select * from BATCH_COUNT_CPT (TABLOCK)

应该做的伎俩,但我不确定它是如何工作的。

如果它在整个交易过程中被锁定,或者只是在选择时被锁定,那也不是很有帮助。

0 个答案:

没有答案