2011-08-08 6 views
7

이 작업을 수행하는 방법은 무엇입니까? My understanding is that this is impossible with TransactionScopes하지만 난 다른 방법으로 해당 작업을 수행하고 싶습니다 :.NET의 중첩 트랜잭션

비즈니스 로직 클래스 : I 트랜잭션의 내부 (아마도 통합 테스트 모두를 캡슐화 할 때까지

public bool Bar() 
{ 
    try 
    { 
    using (var tsWork = new TransactionScope()) 
    { 
     ComplicatedDataImportCode(somedata); 
     FlagRecordInDatabaseAsImported(); // this is the same record that's modified in the catch 
     tsWork.Complete(); 
     return true; 
    } 
    catch (DuplicateDataException err) 
    { 
     // if we got here, the above transaction should have rolled back, 
     // so take that same record in the database and update it to "Duplicate". 
     FlagSameRecordInDatabaseAsDuplicate(err.Message); 
    } 

    return false; 
} 

지금이, 잘 작동 어설 션을 수행 한 후 롤백을 수행하려는 경우).

간단한 테스트는 내 지점을 증명합니다 :

public void CanTest() 
{ 
    // Arrange 
    var foo = new Foo(); 

    using (var ts = new TransactionScope()) 
    { 
    // Act 
    var success = foo.Bar(); 

    // Assert 
    if (success) 
    { 
     Assert.That(SomethingThatTestsThatTheDataWasImported); 
    } 
    else 
    { 
     Assert.That(SomethingThatTestsThatTheRecordWasMarkedAsDuplicate); 
    } 

    // Now that we have been able to perform our Asserts, rollback. 

    } 
} 

궁극적으로, Foo.Bar()의 코드가 있지만 해결책을 수용 할 수 있도록 수정 될 수있다, ComplicatedDataImportCode()의 코드가이 솔루션을 수정할 수 없습니다, 그리고 내가 정말 결과입니다 실패 시나리오에서 제대로 롤백했는지 확인해야합니다.

이 질문의 시작 부분에서 언급 한 게시물에 따르면 다시 한 번, TransactionScopes를 사용하여이 작업을 수행 할 수 없음을 알고 있습니다. 여기서는 TransactionScopes를 사용하여 내가하고 싶은 것을 나타 냈으며이 기능을 구현할 수있는 최상의 대안을 찾고 있습니다.

답변

2

사용중인 DBMS에서 지원해야합니까?

SQL Server는 실제로 중첩 트랜잭션을 지원하지 않지만 SQL Server에서는 savepoints을 사용할 수 있습니다.

An article 나는 몇 년 전에 내 블로그에 썼다.

+1

SQL Server는 중첩 트랜잭션을 지원합니다. 즉, 첫 번째 'ROLLBACK'이 모든 수준을 종료합니다. 'COMMIT'는 중첩을 준수합니다. – Kratz

+0

흠, 아마 SQL Server가이를 지원한다는 잘못된 인식하에 있습니다. 나는 더 많은 것을 배우고 싶다. 귀하의 링크를 읽는 중. +1 지금은 ... – Jaxidian

+0

@Kratz : 귀하의 의견은 바로 내 문제입니다. 나는 ROLLBACK이 모든 것보다는 그 특정한 "내부 트랜잭션"을 롤백하기를 원한다. – Jaxidian

1

ComplicatedDataImportCode이 사용중인 활성 DB 연결을 유지하려면이 연결에서 BEGIN TRANROLLBACK TRAN을 실행하면됩니다.

+0

그러나 부분 롤백은 허용되지 않습니다. 롤백은 전체 트랜잭션을 파기하며 그게 문제입니다. 그래서 내가 말하는 것을한다면, 그 롤백을 수행 할 때, CanTest 메소드에 의해 호출 될 때 같은 트랜잭션 내에 있기 때문에'FlagSameRecordInDatabaseAsDuplicate'에 대한 나의 호출은 작동하지 않을 것입니다. – Jaxidian

관련 문제