문제

내가 사용하는 응용 프로그램의 사건 번호(사이에 다른 유형의 번호).이 번호는 테이블에 저장된"이라는 Number_Setup"을 포함하는 현재 값을의 카운터입니다.

때 응용 프로그램을 생성하는 새로운 사건,그것은 number_setup 테이블을 가져옵 필요한 숫자를 카운터한 행(카운터를 리셋할 수 있습을 매일,매주 등으로 저장됩 int s).그런 다음 incremenets 카운터와 행을 업데이트와 함께 새로운 값입니다.

응용 프로그램은 다중 사용자(약 100 명의 사용자에 한 번뿐만 아니라,sql 실행되는 작업을 잡아 100 의의 사건을 기록하고 요청 시 사용자를 위한 각).사건 표는 몇 가지 중복 사건 번호하지 않아야 합니다.

저장 proc 사용하여 검색하는 다음 카운터입니다.

SELECT @Counter = counter, @ShareId=share_id, @Id=id
FROM Number_Setup
WHERE LinkTo_ID=@LinkToId
AND Counter_Type='I'

IF isnull(@ShareId,0) > 0
BEGIN 
    -- use parent counter
    SELECT @Counter = counter, @ID=id
    FROM Number_Setup
    WHERE Id=@ShareID
END

SELECT @NewCounter = @Counter + 1

UPDATE Number_Setup SET Counter = @NewCounter
WHERE id=@Id

나는 지금 둘러싸인을 차단하는 트랜잭션으로,그러나 나는 완전히 확실하지 않다'100%문제를 해결,생각으로 아직 공유 잠금,그래서 카운터로 읽을 수 있습니다 어쨌든.

아마도 내가 확인할 수 있는 카운터에 되지 않았 업데이트,업데이트 문

UPDATE Number_Setup SET Counter = @NewCounter
WHERE Counter = @Counter
IF @@ERROR = 0 AND @@ROWCOUNT > 0 
    COMMIT TRANSACTION
ELSE
    ROLLBACK TRANSACTION

나는 확실히 이것은 일반적인 문제는 송장 번호에서 금융합니다.
나를 넣을 수 없는 논리 코드에서 하나 잠금을 사용하는 수준이다.저 또한 잠에서 HOLDLOCK 하지만 그것의 응용 프로그램입니다.야에 넣어 두 SELECT?

을 어떻게 확신할 수 있습니 아무 중복이 만들어질까요?

도움이 되었습니까?

해결책

트릭은 마운 업데이트 및에서 읽 단일 원자동:

UPDATE Number_Setup SET Counter = Counter+1
OUTPUT INSERTED.Counter 
WHERE id=@Id;

이것도 지정하지 않은 새로운 카운터를@NewCounter 지만,대신 반환합니다 그 결과로 설정된 클라이언트입니다.당신이해야 할당,사용 중간체 변수 테이블을 출력하는 새로운 카운터로:

declare @NewCounter int;
declare @tabCounter table (NewCounter int);
UPDATE Number_Setup SET Counter = Counter+1
OUTPUT INSERTED.Counter INTO @tabCounter (NewCounter)
WHERE id=@Id
SELECT @NewCounter = NewCounter FROM @tabCounter;

이 문제를 해결을 만드는 카운터가 증가 atomic.당신은 여전히 다른 경쟁 조건에서의 절차 때문에 LinkTo_Id 및 share_id 수 있는 여전히 후 업데이트 첫 번째 선택할 수 있도록 증가 카운터의 잘못된 링크-하는 항목만 해결될 수 없는 그냥에서 이 코드는 샘플로 그것은 현재 온난화 방지에 대한 코드와 비디오 레코더를 업데이트 shared_id 및/또는 LinkTo_Id.

BTW 당신에 가야지마라 채옥의 이름과 일관성있는 경우.면 라는 지속적으로 다음 를 사용하여 정확히 일치하는 경우에는 T-SQL 코드입니다.귀하의 실행하는 스크립트를 지금 그냥 당신이 가지고 있기 때문에 대소문자를 구분하지 않 콜레이션 서버에 배포하는 경우에 민감한 경우 콜레이션 서버의 스크립트와 일치하지 않는 정확한 사건의 현장/테이블을 이름에는 오류를 따를 것이 풍부한 있습니다.

다른 팁

당신은 시도를 사용하여 Guid 를 대신 autoincrements 로 당신의 독특한 식별자?

이 있는 경우 ablity 수정하는 작업을 가져옵 기록 여러,나는 그렇게 생각하는 당신의 카운터는 식별자입니다.다음 얻을 때 당신은 다음 레코드 수지를 삽입하고@@id 니다.는 것을 얻을 수 있도록 하는 것이 가장 큰 숫자입니다.당신은 또한 해야 할 dbccReseed 카운터를 재설정하려면 대신 업데이트할 경우 테이블을 재설정하려 정체성입니다.만 문제는 당신이해야 할 것이 100 그래서 삽입의 일부로 귀하의 sql 작업이 그룹의 정체성입니다.할 수 있는 너무 많은 오버헤드 그러나 사용하는 id 열가 보장해 방법을 고유 번호입니다.

내가 누락될 수 있는 무언가가 있지만,그것은 당신처럼 보인다를 재발견하려는 기술이 있는 이미 해결에 의해 대부분의 데이터베이스가 있습니다.

대신에 읽기 및 업데이트'에서 카운터'열 Number_Setup 테이블,왜 당신은 단지 사용이 자동 증가에 대한 기본 키의 카운터가?지 않을 것이 중복되는 가치에 대한 기본 핵심이다.

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