1

過去数時間、答えを求めてグーグルで検索しましたが、答えが見つからなかったので、ここの誰かが私を正しい方向に向けてくれることを願っています.

TransactionScope 内で EF DbContext (Code-First) を使用してダーティ リードを行う方法を考えています。例えば

DbContext context = new MyEntities();
using(TransactionScope scope = new TransactionScope())
{
    context.SomeTable.Add(someObject);
    context.SaveChanges();

    var objects = context.SomeTable.Where(...).Select(...); //times out here on the read, because the write above locks the tables
    //modify each object
    context.SaveChanges();

    scope.Complete(); //transaction is a success only if the entire batch succeeds
}

次のように読み取り呼び出しをラップしようとしました。

using(TransactionScope scope2 = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions{IsolationLEvel = IsolationLevel.ReadUncommitted}))
{
    var objects = context.SomeTable.Where(...).Select(...); //times out here on the 
}

適切なアプローチは何ですか?

4

3 に答える 3

1

TransactionScope問題が何であるかがようやくわかりました。EF は、L2S が適切に行う方法と統合されていません。これは、EF がサーバーを必要とする操作 (変更の保存またはクエリ) ごとに接続を開いたり閉じたりすることを意味します。

これにより、分散トランザクションと分散デッドロックが発生します。

これを解決するには、手動で EFStoreConnectionを開いたり閉じたりして、トランザクション中に接続が 1 つだけ存在するようにします。

于 2012-12-08T14:13:22.830 に答える
1

このように TransactionScope の IsolationLevel を設定できます...

var transactionOptions = new System.Transactions.TransactionOptions();
transactionOptions.Timeout = new TimeSpan(0, 0, 30);
transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted;
using (var transactionScope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, transactionOptions))
{
...
}
于 2012-12-21T15:12:45.040 に答える
0

サーバー上で実行するだけでalter database your_db_name set READ_COMMITTED_SNAPSHOT on;(SQLServer 2005 から利用可能)、リーダーはライターによってブロックされません (read committed分離レベルでのトランザクションの読み取りを想定)。

于 2012-12-07T23:20:40.077 に答える