首页 > 解决方案 > 为什么 SqlTransaction 被僵尸化了

问题描述

我有一个SqlTransaction执行一些操作,首先删除数据,然后插入SqlBulkCopy. 有时会发生SqlTransactionConnection处理一段时间后设置为 null 并尝试插入更多行并SqlBulkCopy导致错误:

事务要么与当前连接没有关联,要么已经完成

当我查看源代码时,事务被僵尸化时有一个内部状态,我的事务可能进入了这个状态。

有什么方法可以找出交易进入这种状态的原因吗?

例外:

事务要么与当前连接无关,要么已完成。 在 System.Data.SqlClient.SqlBulkCopy.CreateOrValidateConnection(String 方法) 在 System.Data.SqlClient.SqlBulkCopy.WriteRowSourceToServerAsync(Int32 columnCount, CancellationToken ctoken) 在 System.Data.SqlClient.SqlBulkCopy.WriteToServerAsync(DataRow[] 行, CancellationToken cancelToken)

标签: .netsql-server.net-core

解决方案


我试图在 SqlConnection 上打开日志信息消息:

CurrentConnection = new SqlConnection(theConnectionString);
CurrentConnection.Open();
CurrentConnection.FireInfoMessageEventOnUserErrors = true;
CurrentConnection.InfoMessage += CurrentConnection_InfoMessage;


private void CurrentConnection_InfoMessage(object sender, SqlInfoMessageEventArgs e)
{
    var errors = new List<string>();
    if (e.Errors != null)
    {
        for (int i = 0; i < e.Errors.Count; i++)
        {
            errors.Add(e.Errors[i].ToString());
        }
    }

    _logger.LogEvent($"SQL connection info message: source={e.Source}, message={e.Message}, errors={string.Join(',', errors)}");
}

原来有一个僵局

SQL 连接信息消息:source=Core .Net SqlClient Data Provider,message=Transaction (Process ID 134) was deadlocked on lock | 与另一个进程通信缓冲区资源,并已被选为死锁牺牲品。重新运行事务。


推荐阅读