最近の仕事で
(個人的にやや敬遠がちだった)EFを使ってAzureのSQL Databeseに接続するのに
「接続のリトライは実装してね」とお願いしてたら、大掛かりな実装をされた事件があり「おいおーい」と感じたので、メモっておきます。
前提として、現在の開発は
- Visual Studio 2013 update4
- .Net Framework4.5
- Entity Framework6.1.2
そしてC#って感じでやってます。
Overview
MSDNとかみてると、MS用語的には、Connection の Resiliency とか RetryのLogicと言うようですね。
実装方法は、以下です。非常にシンプル。
- DbConfigurationクラスの派生クラスを作って、リトライの設定を持たせる(≒属性を作成する)。
- 対象のDbContextの派生クラスに、属性をつける。
Implimentation : 1
DbConfigurationの派生クラスを作って、そのコンストラクターでSetExecutionStrategyメソッドを呼んでごにょごにょすることで、リトライ回数と再試行間隔を設定します。
今回は、BaseDbConfigurationという名前でクラスを作っています。
public class BaseDbConfiguration : DbConfiguration { public BaseDbConfiguration() { SetExecutionStrategy("System.Data.Sql", ()=>new SqlAzureExecutionStrategy()); } }
ここでの登場人物については、MSDNのリンクを...。
- DbConfiguration クラス (System.Data.Entity)
- DbConfiguration.SetExecutionStrategy メソッド (System.Data.Entity)
SetExecutionStrategyメソッドの2ndパラメーターについてはEntity Framework Connection Resiliency / Retry Logic (EF6 onwards)の「Execution Strategies」あたりを見ました。
今回は、Azure SQL Databaseに接続するので、SetExecutionStrategyメソッドの2ndパラメーターに”SqlAzureExecutionStrategy”を使っています。
上記コードのようにSqlAzureExecutionStrategyのコンストラクターでパラメータを設定しないと、リトライ回数と再試行間隔には既定値がセットされます。
(既定値は、こちらを確認っと。)
自分でリトライ回数と再試行間隔をセットしたい場合は、こんな感じです。
public BaseDbConfiguration() { SetExecutionStrategy("System.Data.Sql", ()=>new SqlAzureExecutionStrategy(5,TimeSpan.FromSeconds(30))); }
Implimentation : 2
前述で作ったBaseDbConfigurationクラスを、DbContextがらみのクラスに属性としてつけます。
今回は、MyDbContextというクラスに属性を付けました。
[DbConfigurationType(typeof(BaseDbConfiguration))] public class MyDbContext : DbContext { ....
完了。シンプルで簡単でした。
実際に使うときは、基本クラスに設定して、必要なクラスに継承させてあげて使えばよいかって感じでしょうか。
201604追記
beachside.hatenablog.com
事故らないためにはここら辺の知識も必要でした....
注意として、独自にトランザクションを利用するときは、多少の細かい実装は必要です。ここでは触れませんが、下の方に参考リンクつけてます。