Reputation: 33605
i have sequences table that consists of three columns:
Number,Year,Type
and for each new year a three new records gets created and updated all along this year.
my stored procedure for generating the sequence is used inside other stored procedures, and my issue is that i want to block concurrent access to this stored procedure and make the access as queue so if concurrent access occur one has to wait for another to finish so that two users don't get same sequence number, the code is as follows:
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
i read that setting isolation level to serializable may solve it, is that enough or i have to use also begin and end transaction in stored procedure and manually handling rollback and commit ?
Upvotes: 1
Views: 1650
Reputation: 33605
I was able to optimize the sequence generation this way:
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
Upvotes: 1
Reputation: 5508
One approach could be the use of SQL Server application locks, see sp_getapplock and sp_releaseapplock. This will let you serialise your sequence generation through the SP without the need for serialisable transactions but won't prevent access to the io_sequecenumbers table by other code so you'll need to be sure that this SP is the only place that updates this table.
Upvotes: 1