티스토리 뷰

IT/Framework

Mybatis - Cursor is closed 해결법

Normal_One 2019. 7. 21. 16:46

 Spring framework 기반으로 Mybatis 설정 완료 후 프로시져를 통해서 리스트 값을 받아올 때 종종 Cursor is closed라는 에러가 발생하는 것을 확인할 수 있습니다. exception으로 throw하기 때문에 난감한 상황이 됩니다. 그렇다고 DB툴을 켜서 프로시져를 실행해보면 정상적으로 응답이 나오는 것을 확인할 수 있습니다. Mybatis에서는 해당 상황이 발생할 때SqlException으로 던지기 때문인 듯 한데, 이를 해결해 주려면 Cursor를 프로시져 도입부에서 무조건 Select 해주면 됩니다. 다만, 값을 내려주면 안되는 상황이고 Select를 태울 필요가 없는데 처음부터 Select가 실행되면 문제가 되기도 하니 아래와 같이 해결하시면 됩니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
CREATE OR REPLACE PROCEDURE TEST_PROCEDURE 
(
    O_CURSOR    OUT SYS_REFCURSOR
) IS
V_ERR01 EXCEPTION;
COUNT NUMBER;
 
BEGIN
   OPEN O_CURSOR FOR 
   SELECT NULL FROM DUAL WHERE ROWNUM = 0;
   -- ROWNUM을 0으로 해줘야 NULL값이 커서에 생성되지 않는다.
   -- Cursor를 명시적으로 무조건 Open하여 Cursor is Closed 방지   
 
   SELECT COUNT(SALARY)
   INTO COUNT 
   FROM EMPLOYEES
   WHERE SALARY > 30000;
   EXCEPTION
     WHEN NO_DATA_FOUND THEN
       NULL;
     WHEN OTHERS THEN
       RAISE V_ERR01;
   -- 말이 안되는 Exception이긴 하나 실제로 여기서 Exception이 발생하고
   -- Cursor가 열리지 않은 상태로 Raise시 Mybatis에서 Cursor is Closed로 Exception을 던지는 걸 확인할 수 있다.
       
   OPEN O_CURSOR FOR
   SELECT SALARY FROM EMPLOYEES
   WHERE SALARY > 30000;    
END TEST_PROCEDURE;
 
cs

 

 정상적으로 돌아갈만한 프로시저는 아니긴한데 예제용이니까 이해해주시기 바라며, 요점은 Raise로 던지기 전에 무조건 Cursor를 한 번은 Open해야 한다는 것 입니다. 위에 적었듯이 Rownum을 0으로 한 이유는 그렇게 하지 않았을 시에 결과값을 받아올 때 Null값이 List 내부에 생기게 됩니다. 많은 도움이 되셨으면 합니다.

 

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday