프로그램개발2016. 3. 11. 13:21




ORA-24784: Transaction exists


트랜잭션이 있습니다.



여러대의 WAS를 이용하는 3Tier 환경에서 데이터를 저장하기 위한 로직을 추가하게 되었는데,


상단의 오류가 발생하였습니다.



자주 보이는 오류는 아닌데,,,, 한번 뜨기 시작하니 엄청나게 많이 뜨더군요~


서비스 할 수 있는 상태가 아니라서 일단, 서비스는 급히 내리고,,,ㅜㅜ



구글이든 다음이나 네이버로 오라클 오류에 대해 찾아보면 그리 많이 나오지는 않습니다.


저 오류의 근본적인 이유는 


ORA-24784: Transaction exists Cause: An attempt was made to start a transaction, while attached to a non-migrateable transaction


어렵네요.


non-migrateable 트랜잭션과 연결된 트랜잭션을 시작하려 했다..



제시된 해결방법으로는


OracleConnection.ClearPool(this.Connection)을 이용하여 생성자에게 넣어주는 것


정도밖에 검색이 안됩니다.



음... 일단, 시스템 환경이 복잡해질수록 이런 류(?!)의 오류 발생 가능성이 높아지는 건 당연하겠고,;;;


처음에 의심이 갔던 곳은 L4 였습니다.


L4 때문에 워낙 고생을 했던지라..


서버가 여러대이다 보니 L4로 로드밸런싱을 하고 있습니다.


DB서버도 여러대로 구성을 해놓은 지라, 모든 부분을 다 알지는 못하는 관계로,,


분산트랜잭션을 사용하는 과정에서 발생하는 것은 아닌가 의심도 가고,..


딱히 해결책이 없는 상태에서, 이것저것 테스트 해보면서 실마리를 찾았습니다.



필요한 데이터를 얻기 위해서는 


연결개체 생성 -> DB 커넥션 오픈 -> 데이터 얻기 -> DB 커넥션 해제 과정으로 진행이 됩니다.


DB 커넥션은 연결된 세션을 무한으로 늘릴 수는 없기 때문에 세션을 열고 닫는 과정을 반복하게 되는데요~


여러가지 방법들이 있긴 하지만,


열러있는 세션을 재활용하여 연결하는 방법(더 디테일하게 설명하기엔 조금 더 공부를 해야겠습니다).!


그 중에서도 트랜잭션으로 돌아가는 세션에게 접근하는 과정에서 발생하는 오류라고 추측이 들었습니다.



음.. 이미 해결방법은 제시된 상태이고,(세션 클리어??)


현재 시스템에서 적용해볼 수 있는 방법은 무엇인가 찾아봤습니다.


간혹, DB LINK를 사용하면 저 에러가 나올 수 있다고 하는데, 저는 DB LINK를 사용하지 않은 단순한 Insert 쿼리이다 보니..


저게 문제는 아니였고,..



일단, DB 커넥션 객체를 생성할 때 초기화 로직을 넣고 싶었지만, 프레임워크 수준에서 정의된 거라 함부로 고치기가 부담ㅜㅜ


프레임쿼크를 뒤져보다 다행히도~ 실행 옵션이 다른 메소드가 있음을 알았고,,


테스트 해보니 해결이 되는 것 같았습니다. Good.!



다른 점은 커넥션이 오픈된 경우, 끊고 재 연결 시키는 로직이었습니다.


음... 의심이 거의 확신으로 가는 순간이었습니다.ㅋㅋ


저는 일단 요렇게 해결을 보았지만, 워낙 많은 상황들이 있기 때문에..


대략 해결방법을 정리해 보자면,



1. 생성자에서 ClearPool을 실행해준다.


2. 커넥션객체 오픈 전에 명시적으로 닫는 과정을 넣어준다.


3. DB LINK를 사용하는 경우에는 로직을 변경해준다.



이 정도 방안을 정리해 보았습니다.



Posted by 하루군 justksh

댓글을 달아 주세요