2

次のコード構造が与えられた場合

func1()
{
    using (TransactionScope1)
    using (connection1)
    {
        "insert into table A"

        func2()

        "select from table B"
    }
}

func2()
{
    using (TransactionScope2)
    using (connection2)
    {
        foreach (x in y)
        {
            "select from table A"
            "insert into table B"
        }
    }
}

TransactionScope2がロールバックされた場合、 で"select from table B"失敗しThe operation is not valid for the state of the transactionます。私が理解しているようにTransactionScope2、最初のものに参加し、両方をロールバックしています。そのため、で作成するように変更したためTransactionScopeOption.RequiresNew、タイムアウトが発生しました"select from table A"

アイデアは、2番目のトランザクションが最初のトランザクションからデータを読み取れるようにすることですが、コミット/ロールバックは個別に行うことです。どうにかして変更する必要があると思いIsolationLevelますが、そのためのオプションがよくわかりません。

編集: and 2 という名前を付けると、おそらく問題を理解しやすくなりますfunc1。基本的func2には DAL 機能であり、andfunc1はその単体テストです。func1いくつかのサンプルデータを作成し、それに対していくつかのアクションを実行し、結果をチェックしてから、成功したかどうかにfunc2関係なく全体をロールバックします。func2

EDIT2:さらに読んだ後、次のコードが機能するはずだと思いますが、何らかの理由でまだタイムアウトが発生しますselect from table A

func1()
{
    using (var txn = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted }))
    using (connection1)
    {
        "insert into table A"
        func2()
        "select from table B"
    }
}

func2()
{
    using (var txn = new TransactionScope(TransactionScopeOption.RequiresNew))
    using (connection2)
    {
        foreach (x in y)
        {
            "select from table A"
            "insert into table B"
        }
    }
}
4

2 に答える 2

2

ネストされた TransactionScopeがあります。

デフォルトでは、それらはリンクされており、それ以上のアクション ( RequiresNew ) がなければ、内側のスコープが失敗すると、外側のスコープは失敗します (RollBack)。

このようにして、それらは独立します。

func2()
{
    using (TransactionScope2 = 
         new TransactionScope(TransactionScopeOption.RequiresNew)) 
    using (connection2)
    {
       ...
    }
}
于 2012-09-19T22:13:26.040 に答える
0

試してみてくださいIsolationLevel.ReadUncommitted

于 2012-09-19T21:29:45.993 に答える