【问题标题】:Why is SqlTransaction zombified为什么 SqlTransaction 被僵尸化了
【发布时间】:2021-08-24 20:21:46
【问题描述】:

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

事务要么与当前连接无关 或已完成

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

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

例外:

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

【问题讨论】:

  • 你在做并行的事情吗? (没有任何代码,仅仅描述问题是不可能帮助你的)
  • @gsharp 是的,该表上还有来自其他进程的其他事务。
  • 然后我会开始看那里。 “有时会发生”听起来像是一个线程有时比另一个更快,并且会扰乱您的连接/事务。
  • 您是否总是在每个线程上使用单个连接和事务?连接和事务对象不是多线程的,应在使用using 块后立即处理。请edit并添加相关代码
  • @Charlieface 我尝试在 SqlConnection 上打开记录信息消息,结果发现出现死锁。奇怪的是,死锁并没有导致异常。

标签: .net sql-server .net-core


【解决方案1】:

我尝试在 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 数据提供程序, 消息=事务(进程 ID 134)在锁上死锁 | 与另一个进程通信缓冲资源并已 被选为死锁受害者。重新运行事务。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-14
    • 2013-04-11
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多