복붙노트

[SQL] SQL 서버 프로세스 큐 레이스 조건

SQL

SQL 서버 프로세스 큐 레이스 조건

I는 저장 프로 시저를 통해 여러 위해 프로세서에 의해 액세스되는 명령 큐를 갖는다. 각 프로세서는 자체 사용을 위해 다음 20 개 주문을 잠그는 데 사용 된 고유 ID에 전달합니다. 저장 프로 시저는 다음에 따라 행동 할 수있는 주문 프로세서에이 레코드를 반환합니다.

다중 프로세서가 그들이 동시에 운영하려고 지적하는 같은 'OrderTable'레코드를 검색 할 수있는 경우가 있습니다. 오류에서이 궁극적 결과는 이후 과정에서 발생된다.

행동의 나의 다음 과정은 가능한 모든 주문 및 단지 라운드 로빈 프로세서하지만 단순히 코드 스레드 안전의이 섹션을 만들 때마다 그들처럼 잡아 레코드 프로세서를 할 수 있도록 기대하고 있었는데 각 프로세서 잡아 수 있도록하는 것입니다.

그래서 명시 적으로 -이 경쟁 조건을 경험하고 어떻게 문제를 해결할 수있는 이유 어떤 생각.

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

해결법

  1. ==============================

    1.편집하다:

    편집하다:

    "READPAST 및 UPDLOCK와 SQL 서버의 데이터 처리 중 대기열"나는 내 대답을 확인 봤. 내가 읽어 본 솔루션을 연주 이후 몇 년이되었습니다.

    기발한:

    당신이 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월

    당신이 선택하고 한 번에 업데이 트를해야하는 경우는 OUTPUT 절을 더 우아하게 수행 할 수 있습니다.

  2. ==============================

    2.당신은 서비스 브로커를 사용할 수 있습니다. : 경쟁 조건을 제거 할 것 - 또한 당신은 당신의 행에 대한 직렬화 액세스에 sp_getapplock을 사용할 수 있습니다

    당신은 서비스 브로커를 사용할 수 있습니다. : 경쟁 조건을 제거 할 것 - 또한 당신은 당신의 행에 대한 직렬화 액세스에 sp_getapplock을 사용할 수 있습니다

    "자신의 자물쇠 (SQL에서 Mutexs)를 작성하여 동시성을 원조" http://sqlblogcasts.com/blogs/tonyrogerson/archive/2006/06/30/855.aspx

  3. from https://stackoverflow.com/questions/939831/sql-server-process-queue-race-condition by cc-by-sa and MIT license