并发问题SQL Server 2012 - 表锁定和唯一索引

时间:2017-10-27 17:39:02

标签: sql-server database stored-procedures locking

我有以下程序:

BEGIN TRANSACTION

    DECLARE @I_NEW_GUIDE BIGINT

    SELECT @I_NEW_GUIDE = MAX(ID_NUM_CAR) + 1 FROM CAR_GUIDE GR WITH (TABLOCKX) 

    SELECT @I_NEW_GUIDE
COMMIT

该过程生成一个序列,即只返回CAR_GUIDE表的“last”字段ID_NUM_CAR并加1。

在稍后的过程中,相同的ID_NUM_CAR将被插入到CAR_GUIDE表中。

我的问题是什么?

  

1 - ID_NUM_CAR无法复制。

     

2 - ID_NUM_CAR可以为空。

我尝试使用序列,但效果不佳。

我最大的问题是访问这个生成顺序的过程的并发性。

示例:当两个进程同时访问该过程时,它们最终会获得相同的MAX(ID)。 ID_NUM_CAR具有唯一索引以防止重复数据。

当这两个进程具有相同的ID_NUM_CAR并且它们用于插入CAR_GUIDE表时,我有一个错误,因为唯一键。

根据ID_NUM_CAR列检索序列的最佳方法是什么?

我尝试过使用SEQUENCE,TABLOCKX,TABLOCK和HOLDLOCK,但效果不佳。

序列

DECLARE @START_SEQ BIGINT = 331, @I_NEW_GUIDE BIGINT

BEGIN
SET @START_SEQ = (SELECT MAX(ID_NUM_CAR) + 1 FROM GUIA_REMESSA);

IF OBJECT_ID('SEQ_ID_NUM_CAR') IS NOT NULL
DROP SEQUENCE [dbo].[SEQ_ID_NUM_CAR]

DECLARE @SQL NVARCHAR(MAX)

SET @SQL = 'CREATE SEQUENCE [dbo].[SEQ_ID_NUM_CAR] 
 AS [bigint]
 START WITH ' + CONVERT(VARCHAR(3), @START_SEQ)
 + ' INCREMENT BY 1
 MINVALUE 331
 MAXVALUE 999999999
 CACHE'

 EXEC(@SQL) 

 SELECT @I_NEW_GUIDE = NEXT VALUE FOR [SEQ_ID_NUM_CAR]

 SELECT @I_NEW_GUIDE

 END

0 个答案:

没有答案