4

Entity Framework を使用し、トランザクション スコープ内で単体テストを実行しています。当初、タイトルにエラーが発生していました。

私は何とか問題を切り分けることができました。

using (TransactionScope scope1 = new TransactionScope())
{
    using (TransactionScope scope2 = new TransactionScope())
    {
           // Here there is no code
    }

    using (Entities se = new Entities())
    {
        EntityConnection entityConnection = (EntityConnection)se.Connection;
        DbConnection storeConnection = entityConnection.StoreConnection;

        storeConnection.Open(); // On this line the error occurs

           // Some code that runs a stored procedure
    }
}

現在発生しているエラーは、「The operation is not valid for the state of the transaction..」です。

トランザクション スコープ 2 を削除すると、すべて正常に動作します。

スコープ 2 をアンビエント トランザクションとしてマークすると、正常に動作します。

4

2 に答える 2

9

明示的なパラメーターなしで scope2 を作成してTransactionScopeOptionいます。これにより、デフォルトの が生成されます。TransactionScopeOption.Requiredセクション内の備考を参照してください。TransactionScope Constructor

このコンストラクターは、トランザクション スコープ オプションが Required に等しい新しいトランザクション スコープを作成します。つまり、新しいスコープにはトランザクションが必要であり、既に存在する場合はアンビエント トランザクションが使用されます。それ以外の場合は、スコープに入る前に新しいトランザクションを作成します。

あなたの例では、アンビエントTransactionScopeは実際に既に存在します ( )。したがって、暗黙的なパラメーターを持つscope1新しいネストされたTransactionScope( )は、新しいトランザクション自体を作成するのではなく、既存のアンビエント トランザクションを使用しています。scope2TransactionScopeOption.Required

ただし、 の暗黙的なトランザクション セマンティクスscope2は引き続き有効です。その結果、 によって作成された既存のアンビエント トランザクションは、 の最後でscope1呼び出していないため、中止されます。Completescope2

このメソッドの呼び出しに失敗すると、トランザクションが中止されます。これは、トランザクション マネージャーがこれをシステム障害、またはトランザクションのスコープ内でスローされた例外と同等のものと解釈するためです。

もちろん、scope2そのセマンティクスを削除または変更するとTransactionScopeOption.RequiresNew( 「スコープに対して新しいトランザクションが常に作成される」ことを意味します) 、問題はすぐになくなりscope1ます。

詳細については、トランザクション スコープを使用した暗黙的なトランザクションの実装を参照してください。

于 2009-08-28T00:49:47.977 に答える
0

この構文はどうですか。これはかなり似ています。Scope2 は完了し、後で破棄されます。

また、断続的に「破棄されたオブジェクト 'トランザクション' エラーにアクセスできません。TransactionScopeOption.Required の代わりに TransactionScopeOption.RequiresNew を使用してこれらの両方を作成する必要があったためでしょうか?

 TransactionOptions rootOptions = new TransactionOptions();
    rootOptions.IsolationLevel = IsolationLevel.ReadCommitted;
    OtherObject.Scope2 = new TransactionScope(TransactionScopeOption.Required, rootOptions);

    TransactionOptions options = new TransactionOptions();
    options.IsolationLevel = IsolationLevel.ReadCommitted;
    options.Timeout = getTransactionTimeout();
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, options))
                {

                                .............
                    scope.Complete();
                }
于 2009-09-15T15:23:23.667 に答える