데이터베이스의 에러 코드를 다루는 작업을 한다고 생각해보자. A 라는 데이터베이스와 B 라는 데이터베이스는 보통 에러 코드가 다를 것이다. 그러면 데이터베이스를 변경할때마다 에러 코드와 관련된 로직과 관련된 예외를 일일이 변경을 해야할까? 이런 불편함을 해소해주는 것이 바로 스프링 예외 추상화 이다.
RuntimeException
을 상속받은 DataAccessException
예외 계층을 제공한다.DataAccessException
은 크게 NonTransient
와 Transient
나뉘어 진다. 쉽게 말하자면 NonTransient
는 다시 sql 문을 DB 에 날렸을 때 복구 불가능한 오류일 가능성이 크고 Transient
은 복구 가능한 오류일 수 있다는 차이가 있다. NonTransient
은 SQL 문법 오류, 중복 키 오류 등이 있다.Transient
는 락, 타임 아웃 과 같은 오류 등이 있다. @Test
void exceptionTranslator() {
String sql = "select bad grammar";
try {
Connection con = dataSource.getConnection();
PreparedStatement stmt = con.prepareStatement(sql);
stmt.executeQuery();
} catch (SQLException e) {
assertThat(e.getErrorCode()).isEqualTo(42122);
//org.springframework.jdbc.support.sql-error-codes.xml
SQLErrorCodeSQLExceptionTranslator exTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource);
DataAccessException resultEx = exTranslator.translate("select", sql, e);
log.info("resultEx", resultEx);
assertThat(resultEx.getClass()).isEqualTo(BadSqlGrammarException.class);
}
}
SQLErrorCodeSQLExceptionTranslator
가 스프링 예외 변환기로 데이터베이스에 상관 없이 발생한 예외를 추상화된 예외로 변환해주는 기능을 수행한다. ex) sql 문법틀림 -> BadSqlGrammarException
의 추상화 클래스 반환exTranslator.translate(설명, sql문, 에러)
SQLException
이 스프링 예외 변환기를 통해서 BadSqlGrammarException
으로 변환된 것이다.데이터베이스가 달라도 스프링 예외 변환기는 각각 데이터베이스마다 에러코드를 잘 캐치해서 추상화 예외로 변환 하여 제공한다. 이러한 과정을 어떻게 수행한 것일까? 바로 비밀은 org.springframework.jdbc.support.sql-error-codes.xml
파일에 있다.