2013-03-04 2 views
1

이 내 스칼라 함수 :이 쿼리에 잠금이 필요합니까?

ALTER FUNCTION [dbo].[GetInstrumentID] 
(
    @ParentDocumentID int 
) 
RETURNS varchar(14) 
AS 
BEGIN 

    Declare @InstrumentID varchar(14) = '' 
    Declare @FilingNumber int = 0 
    Select @InstrumentID = InstrumentID 
     From Documents 
      Where DocumentID = @ParentDocumentID 

    Select Top 1 @FilingNumber = FilingNumber 
     From Documents Where ParentDocumentID = @ParentDocumentID 
      Order By FilingNumber desc 

    Set @InstrumentID = Left(@InstrumentID,9) + Right(
     '000' + Cast((IsNull(@FilingNumber,1) + 1) as varchar(3)) 

    , 3) + '00' 

    Return @InstrumentID 
END 

사용자의 수백이 함수를 호출하면 나는 그들 중 많은 사람들이 같은 반환 값을받을 가능성이 될 것이라고 걱정? 그렇다면 어떻게 한 번에 한 명의 사용자 만이 기능을 실행하고 나머지는 기다리는 것을 보장 할 수 있습니까?

+0

사용'' –

답변

2

두 개의 동일한 동시 호출에 대해 다른 값을 리턴하게하는 함수는 절대적으로 없습니다. 동시성을 막으려면 application locks을 사용할 수 있습니다. SQL Server 2005의 경우 SQL Server 2012에 더 새로운 것이있을 수 있습니다.

+0

어떻게 FilingNumber으로 주문하고 다음 10 사용자가 전화 1. 경우로 그 수를 증가, 어떻게 우리가 같은 신고 번호 것을 gaurantee 수 있습니다 여러 번 생성되지 않을 것입니다. 다른 값을 반환 할 수있는 것이 없으면 가장 행복 할 것입니다. 그러나 여전히 여러 동시 호출에 대해 다른 값을 반환 할 수 있다고 생각합니까? – Jack

+0

또한 당신이 준 링크는 전체 SQL 서버를 잠글 것입니다. 나는 tablock x 같은 무엇인가 있을지도 모른다라고 생각하고 있었다, 또는, 무엇인가? – Jack

+1

함수에서 * Document.FillingNumber' *를 업데이트하지 않습니다 (아마도 외부에서 수행 할 것입니다). 필자는 SQL Server 전문가는 아니지만 최소한이 열의 'UPDATE (업데이트)', 즉 SELECT 및 UPDATE가 포함 된 트랜잭션과 트랜잭션 격리 수준이 SERIALIZABLE로 설정되어 있어야합니다. – ybo

1

UPDLOCK 힌트를 사용할 수 있습니다. UPDLOCK 힌트는 SQL Server 엔진에 "이 행이 UPDATE (잠금"U ")를 얻으려고하면 다른 행을 허용하지 않습니다. 문 또는 트랜잭션이 끝날 때까지 UPDLOCK 잠금을 유지합니다.

Select 문 함수 본문에 : (UPDLOCK, HOLDLOCK)이 문서에서

Select Top 1 @FilingNumber = FilingNumber 
From Documents WITH(UPDLOCK) 
Where ParentDocumentID = @ParentDocumentID 
Order By FilingNumber desc 
관련 문제