c# - 如何编写线程安全的SQL Server存储过程

标签 c# sql-server

我有一些正在执行多个查询的存储过程。为了获得插入的最后标识,我正在使用 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/

相关文章:

C# 命名管道获取要读取的字节数

c# - 创建一个 Guid -> 从 VB 到 C# 的转换

sql - SSRS : Issues with blank Columns

SQL 如何在 SQL 中将数字转换为具有最小小数位数(动态小数位数)的文本

sql-server - 如何将本地 Visual Studio mdf 数据库导出为 Azure SQL 数据库的格式

c# - 退出方法后静态变量丢失了它的值

C# - 如何在字符串中查找字符串,即使它跨越空白?

c# - 如何在不在本地计算机上安装消息队列的情况下从远程计算机读取 MSMQ 消息?

sql-server - 加入具有多行的 2 个表

SQL:如何用相同的值填充两个特定行之间的行?