1

私は3つの列で構成されるシーケンステーブルを持っています:

番号、年、種類

そして、新しい年ごとに 3 つの新しいレコードが作成され、今年を通して更新されます。

シーケンスを生成するためのストアド プロシージャは、他のストアド プロシージャ内で使用されます。私の問題は、このストアド プロシージャへの同時アクセスをブロックし、アクセスをキューとして作成することです。したがって、同時アクセスが発生した場合は、別のストアド プロシージャが終了するまで待機する必要があります。 2 人のユーザーが同じシーケンス番号を取得しない場合、コードは次のようになります。

ALTER PROCEDURE [dbo].[GETSEQUENECENO]
@p_hijricYear                             INT ,
@p_typeId                                 INT ,
@return_val                               INT OUTPUT 
AS 
BEGIN
DECLARE @newSequence                              INT 

BEGIN TRY
SELECT @return_val  = 0
SELECT @newSequence  =  ISNULL( max(correspondencenumber) ,0 )
FROM  io_sequencenumbers with (XLOCK)  
WHERE
hijricyear  = @p_hijricyear
AND
typeid  = @p_typeid
END TRY

BEGIN CATCH
SELECT @newSequence  = -1 
END CATCH

IF @newSequence != -1
BEGIN


IF @newSequence = 0 
BEGIN 
SELECT @newSequence  = 1 
INSERT INTO  io_sequencenumbers    
VALUES 
( @newSequence , 
@p_hijricYear , 
@p_typeId )  
END

ELSE
BEGIN 
SELECT @newSequence  = @newSequence + 1 
UPDATE  io_sequencenumbers   
SET
correspondencenumber = @newSequence 
WHERE  hijricyear  = @p_hijricyear
AND
typeid  = @p_typeid 
END

END -- end of @newSequence!= -1 --

SELECT @return_val = @newSequence
END

分離レベルをシリアライズ可能に設定すると解決する可能性があることを読みましたが、それで十分ですか、それともストアドプロシージャでトランザクションの開始と終了を使用し、ロールバックとコミットを手動で処理する必要がありますか?

4

2 に答える 2

1

この方法でシーケンス生成を最適化できました。

ALTER PROCEDURE [dbo].[GETSEQUENECENO]
@p_hijricYear                             INT ,
@p_typeId                                 INT ,
@return_val                               INT OUTPUT 
AS 
BEGIN
DECLARE @newSequence                              numeric(18,0) 





BEGIN TRY
UPDATE  IO_SEQUENCENUMBERS WITH (READCOMMITTEDLOCK)
SET     @newSequence = correspondencenumber = correspondencenumber + 1
WHERE
hijricyear  = @p_hijricyear
AND
typeid  = @p_typeid
END TRY

BEGIN CATCH
SELECT @newSequence  = -1 
END CATCH

SELECT @return_val = @newSequence

END
于 2015-02-08T09:38:40.990 に答える