2009/07/13 14:10
초급 개발자 이야기/노하우 쌓아가기
| java.sql.SQLException: Cannot call Connection.commit in distributed transaction. Transaction Manager will commit the resource manager when the distributed transaction is committed. |
저도 아직 명확히 어느 부분의 셋팅이 문제가 된 것인지 찾아내지는 못했습니다.
2년전 프로젝트 진행할 때에는 해당 Exception이 떨어지지 않았는데 올해 유지보수에 들어가기 위해 개발환경을 다시 맞추다 보니 발생하더군요.
우선 원인은 transaction이 두번 발생하기 때문입니다.
EJB Containner는 자체적으로 Transaction Controller(이하 EJB TC)를 가지고 있습니다. 대부분 EJB를 사용하실 때는 이 EJB TC를 의지하게 되는데요. 저희처럼 이 EJB TC를 신뢰하지 못하고 프로그램에서 Transaction 처리를 할 경우 문제가 발생합니다.
EJB TC에 의해 Transaction이 처리된 상태에서 프로그램에서 commit()을 호출하거나 AutoCommit 설정을 true로 설정할 경우 두번의 Transaction이 발생하게 되는 것이죠.
이 문제의 해결방법은 EJB Build Configure인 ejb-jar.xml을 수정하는 것입니다.
ejb-jar.xml의 아래 부분을 찾아가 붉은 글씨 부분을 "NotSupported"로 수정해 주시면 됩니다. 대부분 "Required" 설정을 사용하실 겁니다.
| <assembly-descriptor> <container-transaction> <method> <ejb-name>SrmSegmentationEJB</ejb-name> <method-intf>Remote</method-intf> <method-name>*</method-name> </method> <trans-attribute>NotSupported</trans-attribute> </container-transaction> </assembly-descriptor> |
사실 EJB TC를 사용하지 않으면 EJB를 사용하는 의미가 없다는 이야기까지 나오고는 합니다.
현재의 수많은 발전된 Framework들의 Transaction Control은 매우 성능이 좋습니다.
하지만 수년전 EJB의 그것은 그렇지 않은 모양이더군요.
어쨋든 저 Exception에 대해서는 설명과 같이 대처하시면 되겠습니다...^^
'초급 개발자 이야기 > 노하우 쌓아가기' 카테고리의 다른 글
| ie 업데이트 후 애플릿이 실행되지 않을 때 해결 방법 (0) | 2009/07/17 |
|---|---|
| EJB에서 DB Transaction 처리 중 "java.sql.SQLException: Cannot call Connection.commit in distributed transaction. Transaction Manager will commit the resource manager when the distributed transaction is committed." 발생 시 대처 (2) | 2009/07/13 |
| Spring Framework에서 외부 property 사용하기 (0) | 2009/06/08 |
| 비스타에서 "신뢰할 수 있는 루트 기관" 인증서 설치하기 (2) | 2009/01/13 |
| 이클립스에서 등록된 CVS 설정 변경하기 (0) | 2009/01/05 |
| 웹 솔루션에서 외부 프로세스 실행하고 제어하자 (2) | 2008/08/12 |
TAG
Cannot call Connection.commit in distributed transaction,
EJB,
exception,
java.sql.SQLException,
Transaction Manager will commit the resource manager when the distributed transaction is committed


댓글을 달아 주세요
웹로직8에서는 같은 소스로 에러없이 실행되었는데, 웹로직10에서는 con.commit()에서 에러가 나네요. 운영이다 보니, 모든 소스에 관계된 일이라 난해한 상태이구요. 헌데, NotSupported로 바꾸고서 프로그램 내 소스에서도 setAutoCommit(flase);와 con.commit(); 부분을 모두 주석처리하고 테스트해봤습니다. 에러없이 진행되지만 데이터가 들어가지 않을꺼라 예상했는데 데이터가 들어갔더군요..NotSupported로 설정하면 프로그램단에서 트랜잭션 처리를 해야한다고 생각하는데, 그 부분을 주석처리 했으므로, insert가 되지 않아야 한다고 생각했었습니다. 어딘가에서 처리를 해주고 있을까요? 그래서 데이터가 들어간 것일까요? 갈수록 헤매네요...
안녕하세요...^^
음.. 제가 전체 소스를 보지 않은 상태에서 정확히 말씀드리기는 어려울 것 같지만... 아마도....
setAutoCommit(false);를 주석 처리하셨다면 기본으로 auto commit이 활성화가 될겁니다. 그에 따라 JDBC 드라이버 단계에서 자동으로 commit이 실행된 것으로 보이네요.
JDBC 드라이버에 의해 connection이 생성되면 commit 옵션의 기본은 auto commit 상태입니다. 이 auto commit이란 상태가 프레임워크에게 transaction 처리를 위임한다는 의미가 아닌, transaction이 발생했을 때 즉시 처리한다는 의미가 되는 것이죠.
예를 들어 하나의 method에서 여러가지 transaction이 발생한 경우(delete 후 insert 등) JDBC connection이 auto commit 상태라면, delete 후에 commit, 다시 insert 후에 commit으로 각 transaction에 따라 개별 commit이 발생하게 될 겁니다.
따라서 transaction을 수동제어하시기 위해서는 connection object를 사용하시기 전에 setAutoCommit(false)로 auto commit 상태를 변경해 주셔야 합니다.