我有一些正在执行多个查询的存储过程。为了获得插入的最后标识,我正在使用 IDENT_CURRENT
,这是导致问题的原因。
我的问题是,我可以在 T-SQL 中使用像 C# 这样的锁定语句,以便线程安全吗?
编辑:我正在使用的代码
INSERT INTO activities
(creator
,title
,description)
VALUES
(@Creator
,@Tile
,@Description)
SET @ActivityId = IDENT_CURRENT('dbo.activities');
INSERT INTO [dbo].activity_cfs
([activity_id],
[cf_id],
[cf_field_name],
[field_key],
[value])
SELECT
@ActivityId,
cf_id,
cf_field_name,
field_key,
value
FROM @ActivityCustomFields
@ActivityCustomFields
是我的临时表。
最佳答案
您很可能应该使用 SCOPE_IDENTITY
而不是 IDENT_CURRENT
。它们之间的区别有很多解释,例如:What is the difference between Scope_Identity(), Identity(), @@Identity, and Ident_Current?
但是,如果你真的需要保证代码的某些部分不会同时被多个线程运行,你可以使用sp_getapplock
。 .
根据您添加到问题中的代码,我现在很确定您应该简单地使用 SCOPE_IDENTITY
,如下所示:
INSERT INTO activities
(creator
,title
,description)
VALUES
(@Creator
,@Tile
,@Description);
SET @ActivityId = SCOPE_IDENTITY();
INSERT INTO [dbo].activity_cfs
([activity_id],
[cf_id],
[cf_field_name],
[field_key],
[value])
SELECT
@ActivityId,
cf_id,
cf_field_name,
field_key,
value
FROM @ActivityCustomFields;
SCOPE_IDENTITY
函数返回在同一 session 和同一范围内创建的最后一个标识。
IDENT_CURRENT
返回在任何 session 中为特定表或 View 创建的最后一个标识。因此,如果您有多个同时运行此过程的线程,IDENT_CURRENT
将看到在其他线程中生成的标识,这是您不希望看到的。
关于c# - 如何编写线程安全的SQL Server存储过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32219024/