나는 System.Transactions의 기능을 배울 수 있도록 빠른 더미 응용 프로그램을 만들려고합니다. 이 응용 프로그램은 2 개의 다른 SQLExpress DB와 상호 작용합니다. 구성 요소 서비스에서 트랜잭션 통계를 가져 오면 두 번째 연결이 열릴 때 outerScope에서 트랜잭션 시작을 볼 수 있습니다. failOuter가 true이면 트랜잭션은 중단되지만 예외는 발생하지 않습니다. failInner가 true이면 TransactionAbortedException이 발생합니다. MSDN에서TransactionScope을 이해하려고 시도했습니다.
:
응용 프로그램은 트랜잭션에서 수행하고자하는 모든 작업을 완료하면, 당신이 트랜잭션을 커밋 허용하는 트랜잭션 관리자를 알리기 위해 한 번만 완료 메소드를 호출 할 필요가 있습니다. using 블록의 마지막 문으로 Complete에 호출하는 것이 좋습니다.
이 메서드를 호출하지 못하면 트랜잭션 관리자가 트랜잭션을 시스템 오류로 해석하거나 트랜잭션 범위 내에서 throw 된 예외와 동일하게 처리하므로 트랜잭션을 중단합니다.
범위가 트랜잭션을 생성하고 트랜잭션이 중단되면 TransactionAbortedException이 throw됩니다.
그 바탕으로 내 거래 통계는 내가 failOuter 내 응용 프로그램이 true로 설정 실행 중단 된 트랜잭션 매번 보여주는 때문에 내 outerScope가 TransactionAbortedException을 던져 기대. 트랜잭션이 중단 되더라도 예외가 throw되지 않으므로 내 메서드가 true를 반환합니다. 내가 내부 트랜잭션을 중단하지 않으면, 예상대로 동작합니다. 모든 설명이 가장 감사 할 것입니다.
public bool CreateNestedTransaction(bool failOuter, bool failInner)
{
try
{
using (TransactionScope outerScope = new TransactionScope())
{
/* Perform transactional work here */
using (SqlConnection myConnection = new SqlConnection("server=(local)\\SQLExpress;Integrated Security=SSPI;database=test1"))
{
SqlCommand myCommand = new SqlCommand();
myConnection.Open();
myCommand.Connection = myConnection;
myCommand.CommandText = "update test set Value = ((select Value from test where Id = (select max(Id) from test))+1) where Id = (select max(Id) from test)";
myCommand.ExecuteNonQuery();
}
using (SqlConnection myConnection = new SqlConnection("server=(local)\\SQLExpress;Integrated Security=SSPI;database=test1"))
{
SqlCommand myCommand = new SqlCommand();
myConnection.Open();
myCommand.Connection = myConnection;
myCommand.CommandText = "update test set Value = Value";
myCommand.ExecuteNonQuery();
}
using (TransactionScope innerScope = new TransactionScope())
{
using (SqlConnection myConnection = new SqlConnection("server=(local)\\SQLExpress;Integrated Security=SSPI;database=test2"))
{
SqlCommand myCommand = new SqlCommand();
myConnection.Open();
myCommand.Connection = myConnection;
myCommand.CommandText = "update test set Value = ((select Value from test where Id = (select max(Id) from test))+1) where Id = (select max(Id) from test)";
myCommand.ExecuteNonQuery();
}
if (failInner == false) { innerScope.Complete(); }
}
if (failOuter == false) { outerScope.Complete(); }
}
}
catch (TransactionAbortedException)
{
return false;
}
return true;
}
예, 맞습니다. MSDN의 마지막 줄이 나를 떨어 뜨리고 있다고 생각합니다. 내 거래가 중단되고 예외가 발생하는 것을 지켜 보았습니다. 설명 주셔서 감사합니다! 내 외부 예외가 중단되었는지 알 수있는 방법이 있습니까? 이 경우 거짓을 반환하고 싶습니다. –
흠 흥미로운 질문 - 확실하지! 내가 집에 도착했을 때 그것을 확인해 보겠습니다 :) –
예, 일반적으로 사용하게 될 패턴이 아니지만, 할 수있는 방법이 있습니다. 자세한 내용은 편집 된 답변 참조. –