如何在T-SQL中执行事务外部的插入和更新

Ric*_*ich 6 t-sql sql-server transactions

我在SQL Server T-SQL中存储了在事务范围内从.NET调用的过程.

在我的存储过程中,我正在做一些记录到一些审计表.我在审核表中插入一行,然后在事务中稍后通过更新填充更多信息.

我发现,如果有几个人同时尝试同样的事情,其中​​1或2个将成为交易死锁的受害者.目前我假设当我插入审计表时发生了某种锁定.

我想在我正在执行的事务之外执行对审计表的插入和更新,这样即使事务回滚,审计仍会发生.我希望这可能会阻止任何锁定发生,允许一个人同时执行该程序.

任何人都可以帮我在T-SQL中做到这一点吗?

谢谢,Rich

更新 - 我发现审计与事务死锁无关,这要归功于Josh建议使用SQL事件探查器来追踪死锁的来源.

Mit*_*eat 5

TranactionScope支持Suppress:

using (TransactionScope scope = new TransactionScope())
{

    // Transactional code...


    // Call a SQL stored procedure (but suppress the transaction)
    using (TransactionScope suppress = new TransactionScope(TransactionScopeOption.Suppress))
    {
        using (SqlConnection conn = new SqlConnection(...))
        {
            conn.Open();
            SqlCommand sqlCommand = conn.CreateCommand();
            sqlCommand.CommandType = CommandType.StoredProcedure;
            sqlCommand.CommandText = "MyStoredProcedure";
            int rows = (int)sqlCommand.ExecuteScalar();
        }
    }

    scope.Complete();

}
Run Code Online (Sandbox Code Playgroud)

但我不得不质疑为什么日志/审计会在事务之外运行?如果事务被回滚,您仍然会提交审计/记录记录,这可能不是您想要的.

您没有提供有关如何记录的大量信息.您的审计表是否具有指向主活动表的外键?如果是这样,请删除外键(假设审计记录仅来自'已知'应用程序).

  • 嗨,我是在 T-SQL 而不是 .NET 中抑制事务之后。没有带有关系的外键,但我确实记录了涉及到审计表的表的键。 (2认同)

Jos*_*rke 1

为什么要更新审计表?如果您只进行插入,则可能有助于防止锁升级。您还检查过死锁跟踪以确定到底发生了什么死锁吗?

您可以通过启用跟踪标志 1204来做到这一点。或者运行 SQL Profiler。这将为您提供详细信息,让您了解哪种死锁(锁、线程、并行等...)。

查看这篇关于检测和结束死锁的文章。

另一种进行审计的方法是通过将所有日志记录事件发送到应用程序层的队列来与业务事务完全解耦,这可以最大限度地减少日志记录对业务事务的影响,但对于现有应用程序来说可能非常大。