MP의 데이터베이스 트랜잭션 지원

Midnight Peach 2008. 10. 15. 18:03

[주의]
이 글은 MP의 현재 버전 (3.X)에 맞지 않습니다.

단순 참고용으로만 활용하십시오

MP는 LINQ to SQL을 기반으로 하고 있기 때문에, LINQ to SQL가 지원하는 것과 동일하게 데이터베이스 트랜잭션을 지원합니다.

바로 샘플 코드를 보면서 이야기하도록 하겠습니다.

 

샘플은 MemoManager 클래스에 트랜잭션을 타는 삽입 / 갱신 / 삭제 메서드를 추가하는 것 입니다.

MemoManager 클래스에 대해서는 이전 튜토리얼들을 참조하시기 바랍니다.

 

삽입

먼저 트랜잭션을 타는 삽입 작업을 봅시다.

 

 

MemopadDataContext 객체를 생성하고 Memo 엔터티 두 개를 삽입합니다.

SubmitChanges 메서드는 항상 내부적으로 트랜잭션을 타고 있습니다.

따라서 두 엔터티의 삽입 중 하나라도 에러가 발생하면 모든 엔터티의 삽입은 롤백 됩니다.

 

이를 사용하는 단위 테스트 코드를 볼까요?

 

 

Memo 엔터티 두 개를 트랜잭션을 태워 삽입하려고 합니다.

만일 트랜잭션이 커밋되면 삽입하기 전과 삽입한 후의 레코드의 갯수는 다를 것입니다.

하지만 삽입 작업 중 에러가 발생하면 트랜잭션이 롤백 되면 삽입 전후의 레코드의 갯수가 동일할 것입니다.

이 테스트에서는 그것을 체크하고 있습니다.

 

417번 줄은 (Memo의 Subject 에는 null을 입력할 수 없는 것을 이용한) 의도적으로 삽입 에러를 발생시키 위한 코드입니다.

 

테스트 결과는 물론 파란불 입니다.

즉, 첫번째 삽입이 수행된 후의 두번째 삽입에서 에러가 발생하여 첫번째 삽입을 롤백시킨 것을 알 수 있습니다.

 

갱신

이번에는 트랜잭션을 타는 갱신 메서드의 예를 봅시다.

 

 

75번과 78번 줄에서 Clone 메서드를 통해 원 객체의 복사본을 만든 이유는 memo0과 memo1이 로드된 DataContext와 갱신되는 DataContext가 서로 다르기 때문입니다.

로드하는 데 사용된 DataContext는 아마도 위 UpdateInTransaction 메서드를 호출하는 곳에서 생성되었을 것입니다.

반면에 갱신하는 데 사용되는 DataContext는 73번 라인에서 생성됩니다.

Attach 메서드에 대한 자세한 설명은 MSDN을 참고하시기 바랍니다.

 

이 메서드에 대한 단위 테스트 코드는 다음과 같습니다.

 

 

역시 null 값을 허용하지 않는 Memo.Subject 속성에 의도적으로 null을 집어넣어(434 번 줄) 트랜잭션의 롤백을 일으키고 있습니다.

 

삭제

마지막으로 삭제 메서드를 살펴 봅시다.

 

 

복사본을 만들어 DataContext에 Attach 하는 것은 갱신의 경우와 동일합니다.

그리고 DeleteOnSubmit 메서드를 호출하여 삭제 작업을 기록해 둡니다.

실제 삭제는 106번 줄에서 SubmitChanges 메서드가 호출될 때 일어나는데, 기록된 삭제 작업 중 하나라도 에러가 발생하면 전체 삭제가 롤백 됩니다.

 

이에 대한 단위 테스트 코드는 아래와 같습니다.

 

 

코드에서 드러나지는 않지만, Memo 객체는 Reading 객체와 참조 관계를 가지고 있습니다.

따라서 Reading 객체에 연결된 Memo 객체를 삭제하려고 하면 에러가 발생합니다.

450번 라인에서 list[0] 객체는 Reading에서 참조되지 않지만, list[3]는 Reading에서 참조되고 있는 객체입니다.

그래서 두 Memo 객체를 트랜잭션으로 묶어 삭제하는 작업은 롤백이 되어, 삭제 전과 후의 전체 레코드의 갯수는 동일합니다.

테스트는 이 사실을 검증합니다.

: