[펌] 트랜잭션 관련한 타임 아웃의 종류
원글) http://blog.naver.com/PostView.nhn?blogId=sugyoo&logNo=20048409442&redirect=Dlog&widgetTypeCall=true
트랜잭션 관련한 타임 아웃의 종류
① 웹로직 콘솔의 Services – JTA로 설정하는 값의 의미
- 흔히 생각하는 애플리케이션 트랜잭션 타임 아웃의 기능과 웹로직 서버 도메인 혹은 서버 레벨의 트랜잭션 타임 아웃 기능임.
- 웹로직 서버나 도메인 레벨의 트랜잭션 타임아웃은 웹로직 내부적으로 콘솔 작업, 모니터링 혹은 로깅 작업 관련한 웹로직 자체 내부의 트랜잭션 처리를 말함.
- 전역적인 변수로 생각하여도 무방(턱시도의 BLOCKTIME 유사)
- Admin Console에서 JTA Timeout값을 변경 하면 restart 없이 변경 되는 것으로 나오지만,현재 activate되어 있는 resource에는 적용되지 않는다. 해당 EJB를 redeploy 해야만 변경된 Domain의 JTA timeout이 반영된다. 따라서 Domain의 JTA timeout 자체에 대한 값은 restart 없이 반영이 되지만, 이미 activate 되어 있는 관련 resource들은 reactivate를 필요로 하기 때문에 웹로직 서버를 재부팅하여야한다.
② EJB 디스크립터에 존재하는 trans-timeout-seconds
- 특정 ejb 애플리케이션의 트랜잭션 타임 아웃
③ sql statement에 설정할 수 있는 Statement.setQueryTimeout(int sec)
- 원래 java에는 타임 아웃으로 특정 코드를 중지시키는 api등이 존재하지 않는데,jdbc 쿼리에 대하여 타임 아웃을 설정하여 바로 중지 시킬 수 있는 기능이 있고,exception이 발생하므로 에러 코드값을 읽어올 수 있음.
④ XA데이터소스에서 설정하는 XA Transaction timeout
- 각 리소스 즉 흔히 db로 가정하고 그에 대한 처리시 필요한 타임 아웃
⑤ 오라클 데이터베이스인 경우 ora-init파일에 존재하는 DISTRIBUTED_LOCK_TIMEOUT -
- Lock 타임 아웃(default 60 sec)
타임 아웃 관계
위의 그림에서 잘못된 부분이 setQueryTimeout값(웹로직 콘솔에서는 Statement Timeout으로 설정 가능)은 JTA값보다 작게 주어야 한다. 그래야만 악성 쿼리가 돌 때 JTA타임아웃이 적용되기 전에 쿼리를 종료시켜서 추후 rollback으로 인한 T4Cconnection에 대한 lock을 미연에 방지할 수 있는 대안 마련이 된다. 만약 setQueryTimeout 값을 적용하지 않으면 악성 쿼리가 오라클 JDBC드라이버에서 T4Cconnection을 점유하고, Rollback스레드가 이 T4Cconnection이 종료되기를 기다리는 현상이 발생될 수 있으며, 특별한 경우에는 트랜잭션이 종료되지 않고 Rollback 스레드가 무한정 증가하여, 웹로직이 사용자 request조차 받지 못하고, 심지어 웹로직 콘솔도 못들어가는 경우가 발생할 수 있다.
아울러 Statement timeout(setQueryTimeout)을 설정하는 경우 애플리케이션에서 SQLException을 throw하도록 만들어야 한다. 그렇지 않으면 Transaction Manager에서는 정상적으로 수행된 쿼리로 인식하고 commit까지 한다.
- Oracle 데이터베이스의 경우 init 파일의 DISTRIBUTED_LOCK_TIMEOUT 매개변수(디폴트값: 60초)를 XA 트랜잭션 제한 시간 값보다 크게 설정하는 것이 좋다. 그렇게 하지 않으면 WebLogic Server JTA 또는 JDBC XA 트랜잭션 제한 시간에 따라 분산 트랜잭션 시간 초과 상황이 처리되기 전에 Oracle 측에서 테이블이 비정상적으로 잠길 수도 있다.
- 트랜잭션 관련 기본 규칙은 JTA 타임 아웃이 가장 작아야 한다.
- JTA 제한 시간 값이 전역적이거나 EJB에 해당하는 개별 트랜잭션과 적용되는 것과 관계 없이 트랜잭션에 참가하는 모든 Resource에 대해 설정된 제한 시간 보다 가장 짧게 설정되어야 한다. 만약 JTA가 가장 크게 되면 예기치 않은 트랜잭션 배치 결과가 나타날 수 있다. 즉 XAResource가 분산 트랜잭션 코디네이터인 WebLogic Server JTA보다 먼저 제한 시간을 초과하게 되면 XAResource는 WebLogic Server가 인식하기 전에 rollback 과정에 들어가게 된다. 그런데 뒤늦게 타임 아웃이 발생된 것을 알게된 WebLogic 트랜잭션 매니저가 분산 트랜잭션을 commit 혹은 rollback 처리 하려고 들어가게 되면 자칫 휴리스틱(판단을 할 수 없는 모호한 상태) 에러가 발생할 수 있는 것이다.
- Statement.setQueryTimeout(int sec)
- 웹로직에서는 Statement Timeout 파라미터로 default값은 -1로서 사용되지 않는 값
- 초 단위로 타임아웃을 설정하실 수 있고, 이 경우 주어진 시간 내에 query(update 포함)가 종료되지 않을 경우에는 SQLException이 발생된다. (이 시간은 트랜잭션 타임아웃에는 포함되지 않으며, 위의 그림은 서로간의 관계를 표현한 그림이다.)
(ORA-01013: 사용자가 현재 작업의 취소를 요청했습니다)
- Container Transaction인 경우
- weblogic-ejb-jar.xml 안에 <trans-timeout-seconds> 설정이 없는 경우 WebLogic의 JTA timeout을 기본으로 적용 받으며, 설정이 되어 있으면 JTA timeout보다 우선으로 적용.
- Statement.setQueryTimeout(int sec)는 초 단위로 타임아웃을 설정하실 수 있고, 이 경우 주어진 시간 내에 query(update 포함)가 종료되지 않을 경우에는 SQLException이 발생.
- JTA 타임아웃은 단순 looping이나 sleep은 적용되지 않는다.
- UserTransaction 사용시 setTransactionTimeout 메소드로 적용 가능.
댓글 없음:
댓글 쓰기