2016-09-12 4 views
1

트리거를 통해 관련 테이블의 잠금에 문제가 있습니다.SQL Server 트리거 삽입은 커밋 될 때까지 잠금을 발생시킵니다.

테이블 에 레코드를 삽입하기위한 트리거가 있습니다. 테이블 tCatalog에 삽입하고 있습니다. tCatalog에 대한 삽입은 종종 몇 초가 걸리는 많은 다른 기능이있는 트랜잭션 내부에 있습니다. 그러나 tSearchQueue 테이블은 트랜잭션을 커밋 할 수있을 때까지 잠겨 있습니다. 이것을 피할 수있는 방법이 있습니까?

INSERT INTO [dbo].[tSearchQueue] (Processed, SQL, sys_CreateDate) 
    SELECT  
     0, 'Test ' + cast(CatalogID as varchar(10)), getdate() 
    FROM   
     inserted 


BEGIN TRAN t1 
    DECLARE @catalogid int 

    INSERT INTO tCatalog (ProgramID, sys_CreatedBy, ItemNumber, Description, UOMID) 
    VALUES (233, 1263, 'brian catalog4', 'brian catalog4', 416) 

    SELECT @catalogid = SCOPE_IDENTITY() 

    INSERT INTO tCustomAttributeCatalog (CatalogID, CustomAttributeID, DefaultValue, DefaultValueRead, sys_CreatedBy) 
    VALUES (@catalogid, 299, 'No', 'No', 1263) 

    INSERT INTO tCustomAttributeCatalog (CatalogID, CustomAttributeID, DefaultValue, DefaultValueRead, sys_CreatedBy) 
    VALUES (@catalogid, 300, null, null, 1263) 

COMMIT TRAN t1 
+0

*** 왜 ***은'tSearchQueue'가 잠겨 있습니까 ?? 이 동작의 원인은 무엇입니까 ?? 이 문제를 피할 수 있습니까? –

+0

@marc_s 그건 본질적으로 내가 묻고있는 질문이다. tCatalog에 대한 트랜잭션이 아직 커밋되지 않았기 때문에 잠긴 것처럼 보입니다. 나는 그것을 피하려고 노력하고있다. – btorkelson

+0

삽입을 'TCatalog'에 표시 할 수 있습니까? 그 자체만으로도 다른 테이블'TSearchQueue'을 잠그지 않아야합니다 .... –

답변

0

변경 사항에 대한 알림을 받고자하는 백그라운드 프로세스가있는 것처럼 보입니다. 다시 인덱싱을 할 수 있습니다. 이 경우 반드시 이 부당한 것은 아니며이 차단되어 있습니다. 트랜잭션이 커밋하지 않으면 어쨌든 색인을 생성해서는 안되기 때문입니다.

그래서 순서는 다음과 같습니다

  • 삽입 다른 테이블
  • 은 장기 실행 작업을 수행을 tSearchQueue
  • 삽입 거래를
  • 삽입 tCatalog
    • 트리거를 시작
    • 트랜잭션을 커밋합니다.

    그리고 문제는 tSearchQueue을 읽고 싶어하지만이 잠겨있을 수 없기 때문에 또 다른 과정이다.

    옵션 1 : 백그라운드 작업을 일괄 적으로 수행하십시오.

    이 테이블을 읽을 기회가 너무 적기 때문에이 되려면 한 번에 여러 행을 읽는 것이 문제를 해결할 수 있습니다. 나는. 대기열을 읽을 수있는 기회가 생길 때마다 많은 행을 읽고 즉시 처리 한 다음 모두 완료로 표시합니다 (또는 경우에 따라 삭제).

    옵션 2 :

  • 가 장기 실행 작업을
  • 삽입 tCatalog
    • 트리거가
  • tSearchQueue를 삽입 수행 트랜잭션을 시작

    • : 가능하면, 먼저 장기 실행 작업을 수행합니다
    • 다른 테이블을 삽입하십시오.
    • 트랜잭션

    다른 프로세스가 지금 tSearchQueue 짧은 시간 만 잠 깁니다 발견 커밋합니다. 장기 실행 작업이 파일 복사본 인 경우 이러한 작업은 CopyFileTransacted을 사용하여 트랜잭션에 포함되거나 작업이 실패 할 경우 "catch"문에서 롤백 될 수 있습니다.

    옵션 3 : 다른 프로세스가 테이블을 읽을 주로 시도하는 경우 배경 프로세스가 잠금 장치를

    을 방지하고 스냅 숏 격리가 문제를 해결할 수 있습니다. 특정 시점에 존재했던 것처럼 커밋 된 행만 반환합니다. 행 수준 잠금과 결합하면 문제가 해결 될 수 있습니다.

    또는 백그라운드 프로세스는 NOLOCK 힌트 (더티 읽기)로 읽을 수 있습니다. 이로 인해 나중에 롤백되는 트랜잭션에서 데이터를 읽을 수 있습니다. 그러나 별도의 단계에서 데이터의 유효성을 검사하는 경우 (예 : 다시 색인해야하는 객체의 식별자를 작성하는 경우) 반드시 문제가되는 것은 아닙니다. 색인 생성 프로세스가 더 이상 존재하지 않거나 실제로 변경되지 않은 항목에 대처할 수있는 경우 가짜 읽기가 중요하지 않습니다.