System.Transactions에서 Transation (인스턴스에 대한 TransationScope 만들기)을 사용하면 기본적으로 모든 Sql 연결 (System.Data.SqlClient.SqlConnection) (하지만 Oracle.DataAccess.OracleConnection의 경우도 마찬가지 임)이 등록됩니다. 개방시. 그건 자동 입대라고. 좋은 기능. 하지만 연결 문자열의 매개 변수 (enlist = false)를 사용하지 않도록 설정할 수 있습니다. 이 경우 연결이 열리지 않습니다. 하지만 나중에 수동으로 등록 할 수 있습니다. 내 질문은 : 주어진 SqlConnection의 인스턴스에 대해 어떻게 그 연결이 등록되었는지 아닌지 (System.Transaction으로) 결정할 수 있습니다. 매개 변수의 연결 문자열을 볼 수 있습니다. 하지만 이것은 연결이 수동으로 입대 할 수 있다고 말했기 때문에하지 않습니다.SqlConnection이 System.Transactions의 tx에 등록되었는지 여부를 확인하는 방법은 무엇입니까?
5
A
답변
7
프레임 워크가 허용되지 않는 것 같습니다.
아마도이 정보를 알아야 할 이유가있을 수 있습니다. 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;
}
다시 말해서, 이것은 .NET 프레임 워크 내에서 개인 변수와 내부 클래스를 사용합니다. 오늘은 효과가 있지만 내일은 그렇지 않을 수도 있습니다.
좋은 질문입니다. 내 시나리오는 열린 SqlConnection 및 CRUD를 사용하는 정적 메서드 버킷 인 어셈블리가 있다는 것입니다. 호출자가 응용 프로그램 수준의 논리적 손상을 막을 수 있도록 계속하기 전에 SqlConnection을 트랜잭션에 참여 시키도록 강요하는 것이 좋습니다. 우리는'Transaction.Current! = null'을 감지 할 수 있고'SqlConnection conn! = null'을 감지 할 수 있습니다. 그러나 conn이 트랜잭션에 등록되어 있는지 테스트 할 수 없습니다. –