【问题标题】:SqlBulkCopy.WriteToServer hangs Thread.Abort is called but not sure whySqlBulkCopy.WriteToServer 挂起 Thread.Abort 被调用但不知道为什么
【发布时间】:2011-08-13 09:20:41
【问题描述】:

鉴于:

  • BenchMark 类让我知道某事何时完成。
  • 一个非常大的 XML 文件 (~120MB),已被解析为多个列表

一些代码:

SqlConnection con = null;
SqlTransaction transaction = null;

try
{
  con = getCon(); // gets a new connection object
  con.Open();
  transaction = con.BeginTransaction();

  var bulkCopy = new SqlBulkCopy(con, SqlBulkCopyOptions.Default, transaction)
  {
    BatchSize = 1000,
    DestinationTableName = "Table1"
  };

  // assume that the BenchMark class is working
  b = new BenchMark("Table1");
  bulkCopy.WriteToServer(_insertTable1s.AsDataReader()); // _insertTables1s is a List<Table1>
  b.Complete();
  LogHelper.WriteLogItem(b);

  b = new BenchMark("Table2");
  bulkCopy.DestinationTableName = "Table2";
  bulkCopy.WriteToServer(_insertTable2s.AsDataReader()); // _insertTables2s is a List<Table2>
  b.Complete();
  LogHelper.WriteLogItem(b);

  // etc... this code does a batch insert into about 7 tables all having about 40,000 records being inserted.

  b = new BenchMark("Transaction Commit");
  transaction.Commit();
  b.Complete();
}
catch (Exception e)
{
  transaction.Rollback();

  LogHelper.WriteLogItem(
    LogLevel.Critical,
    LogType.DataProcessing,
    e.ToString());
}
finally
{
  con.Close();
}

问题:

在我的本地开发环境中,一切都很好。当我在云中运行此操作时,它会导致它挂起。使用LogHelper.WriteLogItem 方法,我可以看到这个过程的进度。我观察到它随机挂在一张特定的桌子上。不会引发异常,因此不会回滚事务。假设它挂在Table2 批量插入上。使用 MS SQL Management Studio,我在 Table3、Table2 和 Table1 上运行查询没有问题(这意味着事务已中止?)

由于它挂起,我将重新运行该过程。这次它挂得更快,所以我可能会得到这样的日志:

7755   Benchmark   LoadXML took 00:00:04.2432816
7756   Benchmark   Table1 took 00:00:06.3961230
7757   Benchmark   Table2 took 00:00:05.2566890
7758   Benchmark   Table3 took 00:00:08.4900921
7759   Benchmark   Table4 took 00:00:02.0000123

...它挂在 Table5 上(因为 BenchMark 从未完成)。我再次运行它,日志的其余部分如下所示:

7780   Benchmark   LoadXML took 00:00:04.1203923

...它现在挂在这里。

如果有帮助,我正在使用 rackspace 云托管。过去,我可以通过从我的 dbml 文件中删除所有表并读取它们来解决此问题,但这次它不起作用。我想知道正在处理的数据量是否导致了问题?

编辑:此示例中的代码在异步线程中运行。我发现线程因未知原因而中止,我需要找出解决此问题的原因。

【问题讨论】:

  • 您可以尝试在每次批量复制后对事务进行提交,然后看看会发生什么?
  • 我会看看这是否可行,但这并不能解决问题,因为数据是版本化的并且事务需要原子化。
  • 您处理的每个批量插入的行数是什么类型?
  • 大多数表大约为 40000,其中一两个表大约为 500 到 1500。
  • 我确实通过删除服务器上的表并使用 SQL 比较重新同步表模式来解决问题。不是最好的解决方案,所以我正在等待有人提出更好的主意。

标签: c# linq large-files sqlbulkcopy dml


【解决方案1】:

如果你有你的服务器或数据库的管理员,你可以运行

SELECT * FROM sys.dm_tran_session_transactions

查看当前活跃的交易 - 来自Pinal

此外,您可以运行sp_lock 以确保没有任何东西阻止您的交易。

【讨论】:

  • +1 因为这很有用,但这对我没有帮助,因为我的开发和生产环境托管在云中,所以我无权访问该表/视图。
【解决方案2】:

因为这个过程是异步完成的(即启动一个线程来处理这个),所以线程有一个问题会中止它,这就是为什么我会在代码停在不同的地方时出现奇怪的行为。我已经通过同步完成这个任务解决了这个问题(它有效,但并不理想)。

我想真正的问题是为什么我的线程正在中止,因为我没有在我的任何代码中中止它。我相信这是由于正在处理的数据量,但我可能是错的。

不管怎样,我已经解决了我的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-10
    • 2017-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多