Language/Java

Retry JDBC Query execution under specified sql error code (Vendor specific)

OIZTLOMO 2012. 5. 24. 22:24

JDBC API를 이용하여 DML 수행중 Lock이 걸려있거나 특정 이유로 인해 에러가 발생된 경우, SQL Error Code를 설정하여 해당 Query를 재 실행할 수 있도록 설정할 수 있다.


Retry로 설정할 SQL Error Code는 DBMS Vendor 별로 상이하니, 설정시에는 DBMS별 Error Code를 확인한 후 설정하면 된다.


아래 참조할 수 있는 소스에 설정된 Retry & Ignore code는 임의로 가상의 코드를 등록한 것이니 상황에 맞는 code를 사용하면 된다.


SQLException이 발생된 경우, 해당 SQLException의 SQL ErrorCode 값이 Retry Code로 설정된 값이라고 한다면, Retry 를 시도할 때마다 처리 Count 값을 1씩 증가시키고, RETRY로 설정된 회수 값을 초과할 경우 발생된 SQLException을 던져 호출한 곳에서 필요한 처리를 하도록 설정한다.


아래 Sample source에서는 Statement 나 Connection의 close 처리로직은 고려없이 작성되었다.


public class RetryJdbcQuerySample {

// Retry 설정회수

private final int RETRY = 3;


// SQL error code variables for retrying or ignoring sql statements. (Retry, Ignore code 설정은 상황에 맞게 설정해서 사용가능)

private static List<Integer> retryCodeList  = new ArrayList();

private static List<Integer> ignoreCodeList = new ArrayList();


static {

// Retry code가 7125, 7126, 2345 

retryCodeList.add(new Integer(7125));

retryCodeList.add(new Integer(7126));

retryCodeList.add(new Integer(2345));


                // Ignore code가 6666, 6667, 5555 라고 할 경우.

ignoreCodeList.add(new Integer(6666));

ignoreCodeList.add(new Integer(6667));

ignoreCodeList.add(new Integer(5555));

}


public static void executeUpdate(Connection conn, String sql) throws SQLException {  

    Statement st = null;

int count = 0;  

do {  

try {  

st = conn.createStatement();  

int status = st.executeUpdate(sql);

                                // 정상종료일 경우에 Loop 문 탈출  

break;

} catch(SQLException e) {  

System.out.println("SQL statement " + sql + " does not completed successfully");  

System.out.println("ErrorCode: " + e.getErrorCode() + ", SQLState: " + e.getSQLState() + ", Message: " + e.getMessage());

// Retry error code 인 경우

if (retryCodeList.contains(e.getErrorCode())) {

    count++;

        // If count is over than RETRY, throw exception.

        if (count > RETRY) {

        throw e;

        }

System.out.println("Retry Attempt Number: " + count);

// Ignore error code 인 경우

    } else if (ignoreCodeList.contains(e.getErrorCode())) {

        System.out.println("ErrorCode: " + e.getErrorCode() + ", SQLState: " + e.getSQLState() + ", Message: " + e.getMessage());

    break;

    } else {

        System.out.println("ErrorCode: " + e.getErrorCode() + ", SQLState: " + e.getSQLState() + ", Message: " + e.getMessage());

    throw e;

   

} finally {

    if (st != null) try { st.close(); } catch (SQLException sqlEx) {};

}

} while(true);  

}

}