문제

저장 프로 시저를 통해 여러 주문 프로세서가 액세스하는 주문 큐가 있습니다. 각 프로세서는 고유 한 ID로 전달되는 다음 20 개의 주문을 자체 사용하기 위해 잠그는 데 사용됩니다. 저장된 절차는이 레코드를 수행 할 주문 프로세서에 반환합니다.

사례가 있습니다 여러 프로세서가 동일한 'OrderTable'레코드를 검색 할 수 있습니다. 그 시점에서 그들은 동시에 작동하려고합니다. 이로 인해 궁극적으로 프로세스 후반에 오류가 발생합니다.

다음 과정의 과정은 각 프로세서가 사용 가능한 모든 주문을 잡고 프로세서를 Robin을 반올림하는 것이지만,이 코드 스레드 섹션을 안전하게 안전하게 만들고 프로세서가 원하는 때마다 레코드를 가져 오도록 허용했습니다.

그래서 명시 적으로 - 왜 내가이 인종 조건을 경험하고 있는지, 어떻게 문제를 해결할 수 있는지 아는 것입니다.

BEGIN TRAN
    UPDATE  OrderTable WITH ( ROWLOCK )
    SET     ProcessorID = @PROCID
    WHERE   OrderID IN ( SELECT TOP ( 20 )
                                        OrderID
                                FROM    OrderTable WITH ( ROWLOCK )
                                WHERE   ProcessorID = 0)
COMMIT TRAN


SELECT  OrderID, ProcessorID, etc...
FROM    OrderTable
WHERE   ProcessorID = @PROCID
도움이 되었습니까?

해결책

편집하다:

내 답을 확인하기 위해 Googled : "ReadPast 및 Updlock을 사용하여 SQL Server의 데이터 큐 처리". 이 솔루션을 읽고 연주 한 지 몇 년이 지났습니다.

원래의:

ReadPast 힌트를 사용하면 잠긴 행이 건너 뜁니다. Rowlock을 사용하여 잠금 에스컬레이션을 피해야합니다. 내가 알았 듯이 updlock도 필요합니다.

따라서 프로세스 1 잠금 20 행, 프로세스 2는 다음 20을 차지하며 프로세스 3은 41 ~ 60 행을 차지합니다.

업데이트는 다음과 같이 작성할 수 있습니다.

UPDATE TOP (20)
    foo
SET
    ProcessorID = @PROCID
FROM
    OrderTable foo WITH (ROWLOCK, READPAST, UPDLOCK)
WHERE
    ProcessorID = 0

새로 고침, 2011 년 10 월

한 번에 선택과 업데이트가 필요한 경우 출력 절로 더 우아하게 수행 할 수 있습니다.

다른 팁

서비스 중개인을 사용할 수 있습니다. 또한 SP_GETAPPLOCK을 사용하여 행에 대한 액세스를 직렬화 할 수 있습니다.

"자신의 자물쇠를 만들어 동시성 지원 (SQL의 뮤트)"http://sqlblogcasts.com/blogs/tonyrogerson/archive/2006/06/30/855.aspx

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top