82

を使用しTransactionScopeて複数のデータベース クエリをトランザクションにラップするのに問題がありました。バッチ サイズ 500 で SqlBulkCopy を使用しています。バッチ サイズを 1000 に増やすと、次のエラーが発生します。

現在の接続に関連付けられているトランザクションは完了しましたが、破棄されていません。接続を使用して SQL ステートメントを実行する前に、トランザクションを破棄する必要があります。

これは私が使用しているコードです:

using (var scope = new TransactionScope())
{
    using (var connection = (SqlConnection)customerTable.OpenConnection())
    {
        var table1BulkCopy = new SqlBulkCopy(connection)
        {
            BatchSize = BATCH_SIZE,
            DestinationTableName = TableName1
        };

        table1BulkCopy.WriteToServer(table1DataTable);

        var table2BulkCopy = new SqlBulkCopy(connection)
        {
            BatchSize = BATCH_SIZE,
            DestinationTableName = TableName2
        };

        table2BulkCopy.WriteToServer(table2DataTable);

        var table3BulkCopy = new SqlBulkCopy(connection)
        {
            BatchSize = BATCH_SIZE,
            DestinationTableName = TableName3
        };

        table1BulkCopy.WriteToServer(table3DataTable);

        var table4BulkCopy = new SqlBulkCopy(connection)
        {
            BatchSize = BATCH_SIZE,
            DestinationTableName = TableName4
        };

        table4BulkCopy.WriteToServer(table4DataTable);

        scope.Complete();
    }
}
4

7 に答える 7

148

これは、トランザクションがタイムアウトしたときに発生する可能性があります。このようにトランザクションのタイムアウトを増やすことができます (トランザクションの予想される長さに適した値を使用してください)。以下のコードは 15 分間です。

using (TransactionScope scope = 
             new TransactionScope(TransactionScopeOption.Required, 
                                   new System.TimeSpan(0, 15, 0)))
  {
      // working code here
  }

これが、バッチサイズ 500 では機能し、1000 では機能しなかった理由です。

于 2013-01-29T16:35:19.970 に答える
27

TransactionScope でタイムアウトを設定してもうまくいかないことがわかりました。また、次の構成キーをmachine.configタグの最後<configuration>に追加して、デフォルトの最大タイムアウトの 10 分を超えるようにする必要がありました。

<system.transactions>
    <machineSettings maxTimeout="00:30:00" /> <!-- 30 minutes -->
</system.transactions>

クレジット: http://thecodesaysitall.blogspot.com.au/2012/04/long-running-systemtransactions.html

于 2014-01-22T05:25:32.660 に答える
8

ブロックscope.Complete();の外に移動します。connection

using (var scope = new TransactionScope())
{
  using (var connection = (SqlConnection)customerTable.OpenConnection())
   {
    //
   }
  scope.Complete();
}
于 2012-07-12T13:44:10.357 に答える
0

これを適用します:

TransactionScope(TransactionScopeOption.Required, new System.TimeSpan(0, 30, 0));
(0, 30, 0) = (hour,minute,seconds)

テストしたい場合は、この (0, 0, 1) でタイム スパンを適用し、試してみるとエラーが発生します。その後、秒または分または時間を増やして試してください。それが動作します。

于 2021-10-20T11:22:12.653 に答える