当我们使用来自System.Transactions的事务(为一个实例创建TransationScope )时,默认情况下,所有Sql-connection (System.Data.SqlClient.SqlConnection) (但对于Oracle.DataAccess.OracleConnection也不是这样)在打开时都会登记。这就是所谓的自动登记。不错的功能。但是可以通过连接字符串的参数(enlist=false)将其关闭。在这种情况下,打开的连接将不会被征用。但它可以稍后手动登记。所以我的问题是:对于某些给定的SqlConnection实例,我如何确定该连接是否已登记(到System.Transaction中)。我可以查看参数的连接字符串。但这样做是行不通的,因为正如我所说的,连接可以手动登记。
发布于 2008-10-14 04:57:20
这个框架似乎不允许这样做。
也许我们可以讨论一下为什么你需要知道这些信息?TransactionScopeOptions为您在何时创建事务方面提供了一定灵活性。
然而,拒绝回答"no“,之后浏览了一些源代码,我创建了这段代码,它确实有效。请注意,使用框架的补丁时,此代码可能会随时停止运行!
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框架中使用私有变量和内部类。虽然它今天有效,但明天可能不会。
https://stackoverflow.com/questions/199935
复制相似问题