这种方法在负载下是安全的,例如它不会返回任何重复项,即使大量客户端请求同时进入(这是从@remusrusanu 对 SO 上的另一个问题的回答“借用”的)。
基本上,您需要一个带有 columns 的序列表TenantID
,TenantPrefix
然后CurrentValue
您可以使用这样的存储过程来安全地获取新值:
-- add a IDValue column to your Tenant table
ALTER TABLE dbo.Tenant
ADD IDValue INT NOT NULL DEFAULT(0)
-- create this procedure to fetch the next value for any given tenant
CREATE PROCEDURE dbo.GetNextTenantID
@tenantID INT,
@NextID VARCHAR(15) OUTPUT
AS
SET NOCOUNT ON;
DECLARE @Out TABLE (NextVal INT, Prefix CHAR(3))
UPDATE dbo.Tenant
SET IDValue = IDValue + 1
OUTPUT INSERTED.IDValue, INSERTED.IDPrefix INTO @Out(NextVal, prefix)
SELECT TOP 1 @nextID = Prefix + CAST(NextVal AS VARCHAR(10)) FROM @Out
GO
这里的要点是:您必须在单个语句IDValue
中进行递增和返回。只有使用这种方法,您才能在负载下保持安全 - 所有具有第一个、增量然后是不安全的方法并且可以返回重复项。 UPDATE
SELECT
UPDATE
更新:您不能只将这段代码包含到您的更大程序中!保持此过程不变,只需从您的存储过程中调用它 - 例如:
ALTER PROCEDURE [dbo].[AddClient]
(
@TenantId INT,
@FirstName NVARCHAR(100),
@LastName NVARCHAR(100),
@ContactPerson NVARCHAR(100)
)
AS
BEGIN
SET NOCOUNT ON
IF @TenantId IS NULL
RAISERROR('The value for @TenantID should not be null', 15, 1) -- with log
DECLARE @new_person_id INT
DECLARE @new_patient_id INT
DECLARE @ClientIdentifier NVARCHAR(50)
-- call the stored procedure to get the next ClientIdentifier here
EXEC dbo.GetNextTenantID @TenantID, @ClientIdentifier OUTPUT
-- then go on and do your other lines of code from here on out .....
......
END