本文介绍了如何确定的SqlConnection是否被登记到一个System.Transactions的'TX或没有?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我们使用来自System.Transactions的(创建TransationScope一个实例),默认情况下,所有的SQL连接(System.Data.SqlClient.SqlConnection)一TRANSATION(也岂不等于真正的Oracle.DataAccess.OracleConnection)是入伍的开放。这就是所谓的自动征用。不错的功能。但它可以被关闭throught连接字符串的参数(招募=假)。在这种情况下,连接被打开将不征集。但它可以在稍后进行登记。所以我的问题是:对于一些特定的SqlConnection的实例,我怎么能确定连接是否已登记与否(成System.Transaction)。我可以看看该参数的连接字符串。但是,这不会做,因为正如我所说的连接可以人工登记。

When we using a transation from System.Transactions (creating TransationScope for an instance) by default all Sql-connections (System.Data.SqlClient.SqlConnection) (but is't also the true for Oracle.DataAccess.OracleConnection) are enlisted on opening.That's called auto-enlistment. Nice feature. But it can be turned off throught a connection string's parameter (enlist=false). In that case connection being opened wouldn't be enlisted.But it can be enlisted manually later.So my question is: for some given SqlConnection's instance how can I determine whether that connection is enlisted or not (into an System.Transaction).I can look at connection string for the parameter. But this won't do because as I said connection could be enlisted manually.

推荐答案

该框架似乎并没有允许。

The framework doesn't appear to allow that.

或许我们可以讨论为什么你需要知道这些信息?该TransactionScopeOptions为您提供有关何时创建事务有一定的灵活性。

Perhaps we could discuss why you need to know this information? The TransactionScopeOptions give you some flexibility about when to create transactions.

然而,拒绝不的答案,一个小源浏览后,我已经创造了这个code,它确实工作。请注意,这code可以停止在任何时候与补丁程序框架的功能!!!!

However, refusing "no" for an answer, a little source browsing later and I've created this code, which DOES work. Note, that this code could cease to function at anytime with patches to the framework!!!!

    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;
    }

再次,这是利用私有变量和内部类的.NET框架中。虽然今天的作品,它可能不是明天。

Again, this is making use of private variables and internal classes within the .NET framework. While it works today, it may not tomorrow.

这篇关于如何确定的SqlConnection是否被登记到一个System.Transactions的'TX或没有?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-18 14:45