我是事务隔离级别的新手。我也是SQL的初学者。 我有两个存储过程,如下所示。
create PROCEDURE [dbo].[spupdaterecordinfintab]
@IDS BIGINT
AS
BEGIN
begin try
begin transaction
declare @id bigint
set @id = (select [Seedno] from [dbo].[SeedNo] where [Type] = 'abc')+1
DECLARE @INUM NVARCHAR(50)
SET @INUM = 'ABC'+ CAST(@id AS nvarchar(20))
UPDATE [dbo].[exchTab]
SET
[INUMBER] = @INUM
WHERE [id] = @IDS
UPDATE [dbo].[SeedNo]
SET
[Seedno] = @id
WHERE [Type] = 'INV'
EXEC spNEWROECORDINTOfintab @IDS
commit
end try
begin catch
rollback transaction
end catch
END
create PROCEDURE [dbo].spNEWROECORDINTOfintab
@IDS BIGINT
AS
BEGIN
declare @id bigint
set @id = (select [Seedno] from [dbo].[SeedNo] where [Type] = 'abc')+1
DECLARE @INUM NVARCHAR(50)
SET @INUM = 'ABC'+ CAST(@id AS nvarchar(20))
insert into [dbo].[exchTab]
values( @INUM,123.78,1)
UPDATE [dbo].[SeedNo]
SET [Seedno] = @id
WHERE [Type] = 'INV'
END
我希望在我的exchTab tbale中获得inumber中的序列号。多个用户执行时如何实现此目的 [spupdaterecordinfintab]存储过程同时(并发)?哪种事务隔离级别适合?
由于
答案 0 :(得分:0)
我通常在SELECT
指令中使用如下代码,强制对其进行独占锁定:
create PROCEDURE [dbo].spNEWROECORDINTOfintab
@IDS BIGINT
AS
BEGIN
BEGIN TRANSACTION
declare @id bigint
SELECT @id = [Seedno] from [dbo].[SeedNo] WITH (ROWLOCK, XLOCK) where [Type] = 'abc'
SET @id = @id + 1
DECLARE @INUM NVARCHAR(50)
SET @INUM = 'ABC'+ CAST(@id AS nvarchar(20))
insert into [dbo].[exchTab]
values( @INUM,123.78,1)
UPDATE [dbo].[SeedNo]
SET
[Seedno] = @id
WHERE [Type] = 'INV'
COMMIT TRANSACTION
END
此过程中有两个关键部分。第一个是第一个SELECT
,其中包含ROWLOCK
和XLOCK
提示。那些告诉数据库引擎对受影响的行施加独占锁(而不是读取的默认共享锁)。这会阻止此指令上的任何其他并发进程,迫使它们等待proc完成。 ROWLOCK
仅阻止实际的行读取,由WHERE
子句选择。请注意,要使其正常工作,您需要在该列上使用唯一索引,否则您将最终锁定整个表。
另一个重要的部分是交易管理。我在开头添加了BEGIN TRANSACTION
,在结尾添加了COMMIT TRANSACTION
。原因是锁只在交易期间持有。如果省略,每个陈述都构成了自己的交易,因此其他读者可以弄乱表格并获得重复/跳过的数字。