< Go Back

[SPRING] 스프링 프레임워크 데이터베이스 예외 변환

Spring

JDBC API는 SQLException이라는 체크 예외를 반환한다. 따라서 다른 클래스들이 JDBC에 종속적이 되는 문제가 있다. SQLException은 에러를 구분하기 위해 에러 코드를 이용하는데, 데이터베이스마다 이 에러 코드가 다 다르다.

Spring에서는 이 문제를 해결하기 위해 예외 추상화 계층과 예외 번역기를 제공한다. 예외 번역기는 SQLException을 런타임 예외인 DataAccessException으로 바꿔준다. 덕분에 클래스는 SQLException이 아닌 추상화된 스프링 데이터 접근 예외에 의존할 수 있게 된다.

DataAccessException

flowchart BT re[RuntimeException] da[DataAccessException] nt[NonTransient\nDataAccessException] di[Data\nIntegrity\nViolation\nException] bs[BadSql\nGrammar\nException\n] dk[DuplicateKey\nException\n] td[Transient\nDataAccessException] qt[Query\nTimeout\nException\n] ol[Optimistic\nLocking\nFailure\nException\n] pl[Pessimistic\nLocking\nFailure\nException\n] da --> re nt --> da di --> nt dk --> di bs --> nt td --> da qt --> td ol --> td pl --> td

예외는 크게 두 종류로 NonTransientDataAccessExceptionTransientDataAccessException이 있다. 전자는 다시 수행해도 성공할 가능성이 없는 예외들로, 잘못된 SQL을 썼을 때, 중복 키를 사용했을때 등의 상황에 발생한다. 후자는 일시적으로 발생할 수 있는 예외들로, 타임아웃 예외와 락 실패 예외가 해당된다.

SQLExceptionTranslator

SQLExceptionDataAccessException으로 변환하려면 SQLExceptionTranlator 구현체를 사용하면 된다. 에러 코드로 예외가 구분되는 경우라면 SQLErrorCodeSQLExceptionTranlator를 사용하면 된다.

SQLExceptionTranslator.translate() 메소드는 인자로 task, sql, exception을 받아 DataAccessException으로 변환해준다.

catch (SQLException e) {
	SQLExceptionTranslator exTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource);
	DataAccessException ex = exTranslator.tranlsate("select", sql, e);
}