Oracle/Tibero CURRVAL 사용 주의사항
서두
- CURRVAL을 잘못 사용할 경우, 끔찍한 상황이 도래될 수 있다.
- 정말 기본적인 사항을 간과했습니다...
오류
WARN [org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory] (default task-10) IJ030027: Destroying connection that is not valid, due to the following exception: … … 중략 java.sql.SQLException: JDBC-6003: Sequence "AUDIT_REQUEST_ID_SEQ" has not been accessed in this session: no CURRVAL available. |
위의 오류 상황은 다음과 같다.
- API 요청에 대해 감사 로깅을 진행한다.
- API 요청은 3개의 작업을 1개 트랜잭션 으로 작업을 진행한다.
- 감사로그는 3개의 작업에 대해 각각 감사로그를 진행한다. 즉, 총 3개의 감사로깅을 진행한다.
- 첫 번째 감사로그는 NEXTVAL을 사용한다.
- 두 번째, 세 번째 감사로그는 CURRVAL을 사용한다.
Tibero-JDBC-6003오류의 경우, 현재 접속 세션(Connection)에 SEQUENCE.NEXTVAL 없이 SEQUENCE.CURRVAL을 사용했을 때 발생한다.
암호키 등록에 대한 감사로그 입력은 총 3회 실시한다. 첫 번째 감사로그를 입력할 때 NEXTVAL을 호출한다. 두 번째부터는 CURRVAL을 사용한다. 두 번째 감사로그 입력 후, DB Connection Reset이 발생하였다. 해당 사항으로 인해 CURRVAL의 값을 보관했던 커넥션(Session)은 소멸되었다. 그 후, 세 번째 감사로그 입력할 때 CURRVAL을 찾지 못한다.
그러나 위의 상황 분석을 통해 다음과 같이 통찰할 수 있다(다음의 통찰을 통해 쪽팔림 1을 획득할 수 있다.).
- CURRVAL은 NEXTVAL을 호출한 세션에서 호출해야 한다.
- CURRVAL의 값은 Thread-Safe하지 않다.
(은연중에 CURRVAL이 Thread-Safe하지 않은 것을 알고 있었지만, 연계해서 생각을 하지 못 했다......)
그림으로 표현하면 아래와 같다.
- 1개 트랜잭션 내부에서의 NEXTVAL->CURRVAL->CURRVAL은 상관없다고 생각한다(트랜잭션 과정 중 DB 세션이 안죽는다는 가정 하에(트랜잭션 중 DB 세션이 죽으면 그건 또 다른 문제이니까 상관 없을 듯...)).
- 그러나, 위와 같이 별개의 트랜잭션에서의 NEXTVAL->CURRVAL->CURRVAL은 문제가 상당하다. 심각하다. 자세한 사항은 아래 "위의 사항으로 인한 추가 위험"을 참고한다.
위의 사항으로 인한 추가 위험
위의 원인 분석을 토대로 추가 위험사항을 분석한다. 해당 분석은 시나리오 정의와 검증을 토대로 분석을 진행한다. 대표적인 시나리오는 총 두 개,아래와 같다.
- Thread-Safe 하지 않는 값의 사용으로 인해 의도하지 않는 값을 테이블에 적재
- CURRVAL의 잘못된 사용으로 인해 어플리케이션 오류 발생
Time-2) Session2 |
Time-3) Sesseion1 |
- 두 개의 Session의 CURRVAL 값이 다르다.
- 만약, Time-3) Session1의 CURRVAL 값은 2가 아닌, 1이다.
[시나리오2 검증 : 잘못된 사용으로 인한 오류 발생]
현재의 오류가 시나리오2와 같다. 위의 오류는 DBCP 커넥션(세션)의 소멸로 인해 발생하였다. 그러나 많은 동접이 쇄도할 때 아래 그림과 같이 오류가 발생할 수 있다. 모든 요청을 Session1에서 처리하는 것으로 예상하였지만 두 번째 CURRVAL 요청은 Session2에서 처리할 경우 오류가 발생할 수 있다.
부록
- 현재 DBMS는 Tibero이다. 그러나, Oracle 또한 위와 같은 상황이 있을 수 있다 [1].
- 오라클 오류는 "ORA-08002: sequence string. CURRVAL is not yet defined in this session"이다.
[1] http://nimishgarg.blogspot.com/2014/07/ora-08002-sequence-stringcurrval-is-not.html
'개발관련 > 삽질' 카테고리의 다른 글
Apache Commons-DBCP / Hikari-DBCP 정리 (0) | 2021.04.05 |
---|---|
안전한 비동기 처리 전략(Feat. Spring) (0) | 2021.04.02 |
LoRa 1.0 취약점 분석 (0) | 2021.02.04 |
LoRaWAN 1.1 보안 부분 분석(LoRa Spec 6장 일부분 번역) (0) | 2021.02.04 |
Java Enum 활용기(기본/활용/Spring/MyBatis/테스트까지) (2) | 2020.07.20 |