あるデータベースから別のデータベースに大量のデータを変換してインポートするための小さなアプリに取り組んでいます。これを行うために、私はEntity Frameworkといくつかのカスタム拡張機能を使用して、一度に1000程度のバッチでアイテムのページをコミットしています。これには時間がかかる場合があるため、接続の実行中に接続に問題が発生した場合に、全体が停止しないようにすることにも関心がありました。
この記事に従って、EnterpriseLibrary5.0の一部であるTransientFaultHandling Applicationブロックを選択しました(ケース2:トランザクションスコープを使用したポリシーの再試行を参照)。これは、ObjectContext拡張の形式での実装の例です。これは、SQL Azureのものに焦点を当てた再試行ポリシーを使用して、オブジェクトをコンテキストに追加し、それらを保存しようとするだけです。
public static void AddObjectsAndSave<T>(this ObjectContext context, IEnumerable<T> objects)
where T : EntityObject
{
if(!objects.Any())
return;
var policy = new RetryPolicy<SqlAzureTransientErrorDetectionStrategy>
(10, TimeSpan.FromSeconds(10));
var tso = new TransactionOptions();
tso.IsolationLevel = IsolationLevel.ReadCommitted;
var name = context.GetTableName<T>();
foreach(var item in objects)
context.AddObject(name, item);
policy.ExecuteAction(() =>
{
using(TransactionScope ts = new TransactionScope(TransactionScopeOption.Required, tso))
{
context.SaveChanges();
ts.Complete();
}
});
}
実行中にSQLServerのローカルインスタンスを一時停止して再試行ポリシーを実際にテストするまで、コードはうまく機能します。それはほとんどすぐにうんちをします、それは奇妙です。10秒間隔で再試行するようにポリシーが構成されていることがわかります。間隔を無視しているか、エラーをキャッチできていません。後者の疑いがありますが、私はこれに慣れていないので、よくわかりません。