web-dev-qa-db-ja.com

エラー-現在の接続に関連付けられているトランザクションは完了していますが、破棄されていません

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();
    }
}
62
Pradeep

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

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

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

113
Anthony Queen

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

20
Adam

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

using (var scope = new TransactionScope())
{
  using (var connection = (SqlConnection)customerTable.OpenConnection())
   {
    //
   }
  scope.Complete();
}
7
adatapost

タイムアウトにはかなり明らかな問題がありますが、TransactionOptions.Timeoutをより高く設定しても効果はありません。 TimeSpan.MaxValueを設定しても、実際には利益を得ることはありません。 TransactionOptionsのTimeoutプロパティがより高い値に設定されていても問題ありません。TransactionOptions.TimeoutはmaxTimeoutプロパティを超えることはできません。 machine.configでいくつかの変更を設定する必要があります。

まもなくmachine.configファイル%windir%\ Microsoft.NET\Framework \yourversion\ config\machine.configが見つかるはずです。
そしてこれを<configuration> 鬼ごっこ:

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

ここで、maxTimeoutプロパティを30分に設定できます。
詳細については、以下を参照してください http://thecodesaysitall.blogspot.com/2012/04/long-running-systemtransactions.html

0
Vortman

完全な答えはより完全でなければなりません。

.Netコードまたはサーバー構成で-最大トランザクションタイムアウトを決定する場所を指定する必要があります。

<sectionGroup name="system.transactions".... 
    ...allowDefinition="MachineOnly"
</sectionGroup>

この場合、machine.configで最大タイムアウトを設定できます

<configuration>
 <system.transactions>
 <machineSettings maxTimeout="01:00:00" />
 </system.transactions>
</configuration> 

または、アプリケーションでこの動作をオーバーライドすることもできます。次に、machine.configで、速度の属性を設定する必要があります。

...allowDefinition="MachineToApplication"

これは良いアークティックルです: https://blogs.msdn.Microsoft.com/ajit/2008/06/18/override-the-system-transactions-default-timeout-of-10-minutes-in- the-code /

0