반응형

Oracle 로고

 

스프링 프레임워크 기반으로 개발을 진행하고 있었다.

1개의 트랜잭션에서 SELECT, UPDATE, DELETE를 하는 2개의 프로시저를 만들었다.(각각, A와 B라고 하겠다.)

 

1개의 비즈니스 로직에서 A 프로시저를 실행하고, 그 다음에 B 프로시저를 실행하려고 했다.

 

근데, WEB 상에서 해당 로직을 실행시키니 계속 모래시계만 돌아갈 뿐 해당 로직에 대한 리턴값을 받지 못했다.

 

그래서, 아래의 쿼리로 오라클 DB에서 실행중인 쿼리를 조회했다.

SELECT A.STATUS          
     , A.USERNAME  
     , A.SID       -- SID 번호 ((SYSTEM KILL할 때 필요함)
     , A.SERIAL#   -- 시리얼 번호(SYSTEM KILL할 때 필요함)
     , B.SQL_TEXT  -- 쿼리 내용
  FROM V$SESSION S, V$SQLAREA A
 WHERE S.SQL_HASH_VALUE = A.HASH_VALUE 
   AND S.SQL_ADDRESS = A.ADDRESS

 

해당 데이터를 확인해 보니, B 프로시저를 실행했는데 A 프로시저의 쿼리가 락을 잡고 있어서 B프로시저를 진행하면서 데드락이 걸렸다.

 

그래서, 일단 아래의 쿼리로 실행중인 쿼리를 강제 종료를 했다.

ALTER SYSTEM KILL SESSION 'SID,SERIAL#';
ALTER SYSTEM KILL SESSION '199,36768';

 

그렇게 하고 나서, 중간의 프로시저에서 COMMIT을 하면 락이 풀리지 않을까 싶어서 A 프로시저가 끝나기 직전에 COMMIT을 해주고 다시 돌렸더니 똑같이 락이 걸렸다.

 

결국엔, 1개의 스프링 트랜잭션을 사용했던 것을 새로 1개의 트랜잭션을 만들어서 각 트랜잭션에서 A 따로, B 따로 실행을 하였더니 정상적으로 로직이 완료됐다.

즉, CONNECTION을 새로 만들어서 각각 프로시저를 실행했다.

 

원래는 1개의 CONNECTION에서 A와 B를 실행하고 싶었는데 결국엔 락이 걸려서 해당 건은 2개의 CONNECTION을 사용하여 해당 로직을 실행시켰다.

 

반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기