【问题标题】:How to write thread safe SQL Server stored procedures如何编写线程安全的 SQL Server 存储过程
【发布时间】:2015-08-26 06:00:01
【问题描述】:

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

【问题讨论】:

  • 请提供一些代码。我们不能假设您编写了正确的代码:-)

标签: c# sql-server


【解决方案1】:

您很可能应该使用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 函数返回在同一会话和同一范围内创建的最后一个身份。 IDENT_CURRENT 返回在任何会话中为特定表或视图创建的最后一个标识。因此,如果您有多个线程同时运行此过程,IDENT_CURRENT 将看到在其他线程中生成的身份,这是您不想要的。

【讨论】:

    【解决方案2】:

    SCOPE_IDENTITY 将是我理解的方式。请按照以下链接在 SQL Server 中使用 SCOPE_IDENTITY 时始终是线程安全的:

    http://www.vbforums.com/showthread.php?727047-RESOLVED-Is-MSSQL-s-SCOPE_IDENTITY()-thread-safe

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-01
      • 2010-11-06
      相关资源
      最近更新 更多