오늘은 오라클 DB에 값을 직접 수정해 테스트하다가, 엉뚱한 곳에서 원인을 찾느라 한참 돌아간 끝에 문제를 해결했던 경험을 공유해보려고 합니다.
그동안은 DB 값을 UPDATE로 바꾸고 애플리케이션에서 바로 확인하여 테스트하는 게 익숙했습니다. DB UPDATE를 치면 당연히 바로 반영된다고 생각했습니다.
그런데 오라클에서는 이 당연한 생각이 통하지 않았습니다.
문제 상황
추가한 로직이 의도대로 동작하는지 확인해야 했습니다. 가장 빠른 테스트 방법은 실제 값을 하나 바꿔서 확인해보는 것이라고 생각해, SQL Developer로 외부 업체에서 제공한 오라클 DB에 접속해 값을 UPDATE로 수정한 다음, 애플리케이션에서 그 값을 가지고 수행하는 로직이 정상적으로 동작하는지 테스트했습니다.
그런데 의도한 대로 동작하지 않았습니다.
로직 자체가 잘못된 건가 싶었지만, 그건 아니었습니다. 같은 로직을 쓰는 다른 곳에서는 똑같은 방식으로 테스트해도 문제없이 잘 동작하고 있었기 때문입니다.
그럼 대체 무슨 차이인가 싶어 비교해봤는데, DB 종류가 달랐습니다. 정상적으로 동작하는 쪽은 PostgreSQL을, 안 되는 쪽은 오라클을 쓰고 있었습니다.
접속 포인트가 두 개라 다른 테이블을 보는 걸까?
오라클 쪽은 접속 포인트를 두 개 받아서 쓰고 있었습니다. 하나는 SQL Developer로 직접 접속하는 포인트였고, 다른 하나는 애플리케이션이 연결하는 포인트였습니다. 이름과 스키마는 같아 보이지만 실제로는 서로 다른 테이블을 바라보고 있는 게 아닐까 의심했습니다.
이전에는 오라클을 써본 적이 없기에, 같은 스키마.테이블 이름인데도 접속 정보에 따라 실제로 다른 대상을 바라보는 경우가 있는지 GPT한테 물어봤습니다. 특정 구성에서는 그럴 가능성도 있다는 답을 받았고, 저는 이걸 거의 확정적인 원인으로 받아들였습니다.
그래서 외부 업체에 요청해서 특정 계정 하나로만 접속해서 조회·수정할 수 있도록 권한을 다시 정리해달라고 했습니다. 접속 경로를 하나로 좁히면 “다른 테이블을 보고 있다”는 가설을 검증할 수 있을 거라고 생각했습니다.
하지만 요청한 대로 권한이 정리되어도 여전히 의도대로 동작하지 않았습니다.
그럼 테이블 자체가 꼬인 걸까?
접속 경로 문제가 아니라면 테이블 자체가 이상한 건 아닐까 생각했습니다. 그래서 혹시나 싶어 테이블을 드랍하고 새로 만들어달라고 요청했습니다.
업체 측에서는 요청대로 처리하려다, 테이블에 락이 걸려 있는걸 발견해 우선 해당 락만 종료했다고 했습니다.
그 얘기를 듣고 옆에 계시던 선배가 저에게 물어보셨습니다.
“혹시 커밋 안 한 거 아니야?”
뜻밖의 질문
저는 당연히 오토커밋일 거라고 생각하고 UPDATE만 치고 확인했다고 답했습니다. PostgreSQL로 테스트할는 항상 그렇게 해왔으니까요. 그래도 혹시 모르니 한 번 직접 COMMIT을 날리고 다시 해보라는 말을 들었습니다.
1
2
3
4
5
UPDATE SOME_TABLE
SET SOME_COLUMN = '테스트값'
WHERE SOME_ID = '1234';
COMMIT;
COMMIT을 날리고 나서 다시 테스트해보니, 그제서야 정상적으로 동작했습니다.
알고 보니, 오라클은 오토커밋이 꺼져 있었습니다…
정확히는 “오라클 DB 자체”가 오토커밋을 지원하지 않는다기보다는, 제가 값을 수정할 때 쓰던 SQL Developer 세션의 기본 동작이 오토커밋이 아니었던 것이었습니다.
PostgreSQL 클라이언트에서는 보통 기본값이 오토커밋이었기 때문에, 저는 이 차이를 전혀 생각하지 못한 채 오라클에서도 그냥 UPDATE만 치고 결과를 확인해왔던 것이었습니다…
오라클은 커밋하지 않은 상태에서도, 값을 수정한 세션 자신에게는 그 변경 사항이 바로 조회됩니다. 하지만 다른 세션(다른 SQL Developer 세션이든, 애플리케이션의 JDBC 커넥션이든)에서는 마지막으로 커밋된 값만 보입니다.
저는 제 세션에서만 보이는 값을 “정상적으로 반영된 값”이라고 착각했고, 애플리케이션이 이전 값을 그대로 쓰는 걸 보면서 “접속 포인트가 두 개라 서로 다른 테이블을 보고 있는 게 아닐까”라고 오해했던 것입니다. 실제로는 테이블이 두 개였던 게 아니라, 커밋되지 않은 값과 커밋된 값을 각각 다른 세션에서 보고 있었을 뿐인데요…
돌이켜보면 테이블을 드랍하려 할 때 걸려 있었다던 그 락도, 다름 아닌 제가 커밋하지 않고 방치해둔 트랜잭션이 쥐고 있던 락이었을 가능성이 커 보입니다…
왜 오토커밋이 꺼져있다는 걸 늦게 알아챘을까
당시에는 다음 흐름을 의심 없이 그대로 믿고 있었습니다.
1
DB에 UPDATE를 친다 → 바로 반영된다 (PostgreSQL에서 늘 그래왔던 것처럼)
그런데 이 전제 자체가 오라클에는 그대로 적용되지 않았습니다. DB마다, 정확히는 접속하는 클라이언트/툴마다 오토커밋 기본값이 다를 수 있다는 걸 몸으로 겪고 나서야 알게 됐습니다.
게다가 하필 접속 포인트가 두 개였다는 사실이 “테이블이 다른가?”라는 그럴듯한 가설을 만들어냈고, 그 가설에 한번 꽂히니 권한을 다시 정리해달라고 하고 테이블까지 새로 만들어달라고 할 때까지도 정작 제일 먼저 확인했어야 할 커밋 여부는 의심조차 하지 않았습니다.
느낀 점
- 같은 증상이라도 원인은 눈에 보이는 것과 다를 수 있다.
- 저는 “테이블이 두 개인 것 같다”고 느꼈지만, 실제로는 테이블은 하나였고 세션마다 보이는 버전이 달랐던 것뿐이었습니다.
