10

SqlBulkCopyからのシーケンシャルタイムアウト例外をカウントする必要があります。これをテストするために、外部アプリを使用してトランザクションを開始し、ターゲットテーブルをロックします。

SqlBulkCopyは、最初の呼び出しでのみ、予期したときにタイムアウト例外をスローします。外部接続とトランザクション、および接続文字列と内部トランザクションを使用してみました。外部接続とトランザクションでは、接続を開いたり、トランザクションを開始またはコミットしたりするのに無限の待機が発生することはありませんでしたが、常にで待機していました.WriteToServer()

制限SqlBulkCopy.WriteToServer()に達したときにタイムアウト例外を確実にスローする、これに対するいくつかのアプローチはありますか?.BulkCopyTimeout

public void BulkCopy(string connectionString, DataTable table, int bulkTimeout)
{
    using (SqlBulkCopy bulkCopy = new SqlBulkCopy(
        connectionString, 
        SqlBulkCopyOptions.UseInternalTransaction))
    {
    bulkCopy.BulkCopyTimeout = bulkTimeout;//e.g. 120 sec.
    //... fill with data, map columns...
    bulkCopy.WriteToServer(table);
    // ^^^^ waits indefinitely, doesn't throw until *after*
    //      the lock is released.
    }
}

ブロックのスコープ内で例外を処理するのではなく、例外をバブルアップさせる方usingが好きですが、いつでも再スローできます。洞察に感謝します。

アップデート1:

まだ解決策はありません。ただし、興味深い動作が発見されました。通常のSqlCommandは、SqlBulkCopy.WriteToServerメソッドが無期限にハングするのと同じロック中に、期待どおりにTimeoutExceptionをスローします。

SqlBulkCopy.WriteToServerが予期したときに一貫してタイムアウトをスローするようにするために、私たちが試した(そして失敗した)アプローチは次のとおりです。

  • MARS(複数のアクティブな結果セット)のオン/オフ
  • TableLockのオンとオフ
  • ヒープテーブルとインデックステーブルとしての宛先
  • より長い/より短いBulkTimeout値(10秒から5分)
  • 内部トランザクションと外部トランザクション

今のところ、回避策として、a)WriteToServer呼び出しを非同期ラッパーに入れて、自分で時間を計ることができるようにすることと、b)WriteToServerを1回だけ呼び出すことを交互に行っています。タイムアウト後、通常のSqlCommandが成功するまで待ってから、 WriteToServerを再試行してください。これらのアプローチを使用することで、少なくとも実行フローの制御を維持することができます。

4

2 に答える 2

5

SqlBulkOptions.TableLockオプションをSqlBulkCopyに渡してみましたか?そのオプション(引用符)は、次のことを意味します。

一括コピー操作中に一括更新ロックを取得します。

したがって、テーブルをロックする別の処理がある場合、ロックが取得されるのを防ぎ、理論的には確実にタイムアウトします。

更新:
独自のテストハーネスを設定しましたが、再現できません。テーブルをロックするために、SSMSでトランザクションを開始しましたSELECT * FROM TargetTable WITH (HOLDLOCK)。質問に含めたのと同じBulkCopyメソッドを使用し、内部トランザクションを使用して、バルクロードタイムアウトを30秒にしました。一括コピーを実行しようとするたびに、30秒後に予想どおりにタイムアウトになります。その後、SSMSトランザクションをロールバックすると成功します。

SQL Server 2008 Express、.NET3.5を使用していました。

最初の試行の後、バルクロードタイムアウトが正しく渡されていないようなものではありませんか?つまり、どういうわけか「不定」に設定されていません。

更新2:
接続文字列で複数のアクティブな結果セットのサポートもオンに切り替えましたが、それでも毎回常にタイムアウトになります。

于 2010-02-05T18:29:44.297 に答える
2

後でこの問題が発生しました。この問題を解決するには、BulkCopyTimeoutをゼロに設定します。

bulkCopy.BulkCopyTimeout = 0;
于 2010-02-07T05:34:59.803 に答える