2009-02-06 3 views
1

레거시 애플리케이션은 JDBC 3.0을 사용합니다. 각 스레드에 대해 동일한 JDBC 연결을 리턴 할 수있는 자체 트랜잭션 관리자를 구현하여 트랜잭션을 지원합니다. 최근에 발견 한 문제점은 중첩 된 트랜잭션을 지원하지 않는다는 것입니다. 트랜잭션이 다른 트랜잭션 내에서 시작되면 내부 트랜잭션의 컨텍스트에서 실행되는 모든 SQL은 동일한 db 연결을 사용하여 실행되고 커밋되거나 롤백하면 외부 트랜잭션부터 시작하여 모든 변경 사항을 자동으로 커밋하거나 롤백합니다.JDBC 3.0을 사용하여 중첩 된 트랜잭션에 대한 지원 구현

JDBC 3.0 세이브 포인트를 사용하여 중첩 트랜잭션에 대한 지원을 구현할 수 있습니다. 중첩 트랜잭션이 시작될 때마다 현재 연결에 대해 새 세이브 포인트를 설정할 수 있습니다. 이후에 중첩 트랜잭션이 롤백되면이 세이브 포인트로 롤백됩니다. 반면에, 그것이 커밋된다면, 나는 아무것도하지 않을 것입니다. 가장 외부 트랜잭션의 커밋 만 db에 대한 변경 사항을 저장합니다.

이 정보가 맞습니까? 이 접근법에는 결함이 있습니까? 그렇다면 내 가능성은 무엇입니까?

감사합니다.

답변

1

트랜잭션은 약간 까다 롭습니다. 실제로 JDBC 계층에서 볼 수는 없지만 기본 데이터베이스 자체에서 볼 수는 있습니다. 내가 오라클에 관해서 이야기 할 것입니다. 오클라호마가 가장 경험이 많기 때문입니다. 오라클에서 트랜잭션을 시작하면 트랜잭션 내의 저장 점으로 롤백 할 수 있지만 세이브 포인트를 사용하여 커밋 할 수는 없습니다. 그래서 트랜잭션을 시작하고 A, B, C 세 개의 세이브 포인트를 가지고 있다고 가정 해 봅시다. A, B 또는 C로 행복하게 진행하고 롤백 할 수 있지만 일단 커밋하면 새 트랜잭션을 시작하고 이제 A, B , C는 더 이상 유효하지 않습니다. 이 질문이 도움이되기를 바랍니다.

1

지연 수준보다는 커밋이 필요한 코드에 종속성이있을 수 있습니다 (예 : 격리 수준이 TRANSACTION_READ_COMMITTED로 설정된 경우).

별도의 연결에서 중첩 트랜잭션을 수행하도록 트랜잭션 관리자를 수정하는 것이 좋습니다.

업데이트 : the Spring framework은 SavePoints를 사용하여 중첩 된 트랜잭션을 제공합니다. 내 생각 엔 그들은 격리 모드의 문제를 그냥 무시한다는 것입니다.

+0

?중첩 된 트랜잭션은 다른 연결에서 수행 되었더라도 이전에 커밋 된 후에도 롤백됩니까? – Stas

+0

아니요, 중첩 트랜잭션은 롤백되지 않으므로 더 이상 실제로 "중첩"되지 않습니다. – jdigital

+0

Spring은 격리 문제를 무시하지 않습니다. http://www.ibm.com/developerworks/java/library/j-isolation/ – duffymo

1

Atomikos TransactionsEssentials에서 중첩 트랜잭션 지원을 시도 할 수 있습니다.

그러나, DBMS에 중첩 된 트랜잭션은 일반적으로 다음과 같은 방법으로 제한됩니다 :

당신의 중첩 된 트랜잭션이 롤백 단위의 비용으로 공유 데이터 액세스를 허용하는 동일한 DB 트랜잭션을 공유 -either (당신은 전체를 롤백 것)

- 또는 당신의 중첩 된 트랜잭션은 핫스팟 데이터

이 불일치는 데이터베이스 트랜잭션의 ACID 성격에 기인위한 공유 데이터 액세스를 허용하지의 비용으로, 다른 기본 DB의 트랜잭션() Atomikos로 매핑됩니다. 결국 모든 DBMS 액세스는 이러한 데이터베이스 트랜잭션에서 발생하도록 제한됩니다.

당신이 뭔가를 감싸고 싶다면, 언급 한 세이브 포인트 접근법은 유망한 것으로 들릴지 모르겠다.하지만 아마도 광범위하게 테스트해야 할 것이다.

최저 가이

외부 트랜잭션이 롤백 그것에 대해 생각,하지만이 경우에 일어날 것
관련 문제