.NETで作成したアプリケーションからDBアクセスした際にタイムアウトが発生した場合、以下の原因が考えられる。
1.トランサクションタイムアウト
トランザクションには、トランザクションタイムアウトという機能があります。
これは、トランザクションが開始されると同時にトランザクションの経過時間を監視し、
一定の時間に到達するとトランザクションを自動的にロールバックする機能です。
例えばデータの更新中にクライアントのPCがシャットダウンしアプリケーションが終了してしまった場合、データベースの占有してしてしまうことになるので他のクライアントからのアクセスでトランザクションの待ち状態が発生してしまいます。
一定の時間でトランザクションをロールバックさせることで、このように予期せぬ事態が発生したさいもトランザクションの待ち状態を短くすることができるのです。
データの一貫性を保つためには大切な機能なのですが、
これが原因で膨大なデータ操作を行う際に、タイムアウトが発生してしまうことがあります。
トランザクションのタイムアウトが発生した場合は、
サーバー/クライアントどちらの処理で時間がかかっているのか確認すること。
待機時間の初期値は1分
これ以上伸ばしたい場合は、
TransactionScope.Timeoutプロパティに時間を指定する。
using(var tran = new TransactionScope(TransactionScopeOption.Required,new TimeSpan(0,10,0))
isolationレベルも指定したい場合は、以下のようになる
var transactionOptions = new TransactionOptions();
transactionOptions.IsolationLevel = IsolationLevel.ReadUncommitted;
transactionOptions.Timeout = new TimeSpan(0, 10, 0);
using(var tran = new TransactionScope(TransactionScopeOption.Required, transactionOptions));
↓(1行で書いてもよい)
using(var tran = new TransactionScope(TransactionScopeOption.Required,new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted,Timeout = new TimeSpan(0,10,0)}))
※待機時間を10分以上に設定したい場合は、machine.configで設定する必要がある。
machin.configはサーバー単位で共有されるため、慎重に。
2.Sqlコマンドのタイムアウト
1つのコマンド単位の待機時間。
規定値は30秒。
ObjectContext.CommandTimeoutプロパティで設定する。