6

System.Transactions からのトランザクションを使用する場合 (インスタンスの TransationScope を作成する)、デフォルトですべての Sql 接続 (System.Data.SqlClient.SqlConnection) (ただし、Oracle.DataAccess.OracleConnection には当てはまりません) を開くときに登録されます。 . いわゆる自動入隊です。素敵な機能。ただし、接続文字列のパラメーター (enlist=false) を使用してオフにすることができます。その場合、開かれている接続は登録されません。ただし、後で手動で登録できます。したがって、私の質問は次のとおりです。特定の SqlConnection のインスタンスについて、その接続が (System.Transaction に) 登録されているかどうかを判断するにはどうすればよいですか。パラメータの接続文字列を見ることができます。しかし、私が言ったように、接続は手動で参加できるため、これはうまくいきません。

4

1 に答える 1

10

フレームワークはそれを許可していないようです。

おそらく、なぜこの情報を知る必要があるのか​​について話し合うことができますか?TransactionScopeOptionsを使用すると、トランザクションをいつ作成するかについてある程度の柔軟性が得られます。

ただし、答えに「いいえ」を拒否し、後で少しソースを参照して、このコードを作成しました。これは機能します。このコードは、フレームワークへのパッチを適用するといつでも機能しなくなる可能性があることに注意してください!!!!

    static bool IsEnlisted(SqlConnection sqlConnection)
    {
        object innerConnection = typeof(SqlConnection).GetField("_innerConnection", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).GetValue(sqlConnection);
        var enlistedTransactionField =
            EnumerateInheritanceChain(innerConnection.GetType())
            .Select(t => t.GetField("_enlistedTransaction", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy))
            .Where(fi => fi != null)
            .First();
        object enlistedTransaction = enlistedTransactionField.GetValue(innerConnection);
        return enlistedTransaction != null;
    }

    static IEnumerable<Type> EnumerateInheritanceChain(Type root)
    {
        for (Type current = root; current != null; current = current.BaseType)
            yield return current;
    }

繰り返しになりますが、これは.NETFramework内のプライベート変数と内部クラスを利用しています。今日は機能しますが、明日は機能しない可能性があります。

于 2008-10-14T04:57:19.753 に答える