예외 블랙홀
이런 예외처리로 해왔는데..
따로 작업처리를 추가해 줘야된다..!
별로 의미없는 코드 나쁜습관이다..
어떻게 예외를 다뤄야 될까?
ERROR
VM에서 발생시키는 에러이므로 굳이 안잡아도 된다.
Exception과 체크 예외
Exception 2가지로 체크 예외와 언체크 예외로 나뉜다.
전자는 Exception 서브 클래스 이면서 RuntimeException 클래스 상속 X
후자는 RuntimeException 클래스에 상속되는 친구들
전자는 좀 특별하게 다룸.
체크예외가 발생할 수 있는 메소드를 사용할 경우 반드시 예외처리를 하는 코드도 작성해야ㅑ됨
try/catch
ERROR와 동일하게 굳이 catch나 throw로 선언하지 않아도 됨.
다시읽어볼 내용들 체크.
런타입 에러는 예쌍하지 못했던 예외상황에서 발생하는게 아님 굳이 catch나 throw를 사용 하지
않아도 되도록 만듬.
요즘은 가능한 예외상황을 다루는 예외를 체크 예외로 만들지 않는 경향임
드물게 사용함..
예외를 메소드 밖으로 던짐.
적절한 예외로 전환해서 던진다.
중첩예외로 만들어도 좋음
주로 예외처리를 강제하는 체크 예외를 언체크 예외인 런타임 예외로 바꾸는 경우에 사용
대표적으로
EJBException
코드에서 로직상 예외조건이 발생할 경우 체크 예외를 사용하는것이 바람직 하다..
최근에는 예외를 체크 예외 대신 언체크 예외로 정의하는것이 일반화됨.?
런타입 예외로 포장해 던져버리면 그 밖의 메소드들이 신경 쓰지 않게 해주는 편이 좋다.
런타임 에러로 처리하고 좀더 명확하게 에러를 표시해주기 위해 DuplicateUserIdException 날려준다.
런타임 예외를 일반화해서 사용하는 방법은 장점이 많음
사용할때 더 주의를 기울일 필요도 있음.
신경쓰지 않으면 예외상항을 충분히 고려하지 못하기 때문에.
런타임 예외 중심 전략 -> 낙관적인 예외처리 기법
복구할 수 있는 예외는 없다 가정 -> 어짜피 예외 생겨도 시스템 레벨에서 처리.
애플리케이션 자체의 로직에 의해 의도적 발생 및 반드시 catch 해서 무엇인가 조취하도록 하는 예외는 애플리케이션 예외라고 함.
스프링의 예외처리 전략 원칙
SQLExcption은 복구방법 X
필요없는 기계적인 throws 선언이 등장하도록 방치하지말고 가능한 빨리 언체크/런타임 예외로 전환해줘야된다.
JDBC는 모든 SQLExcption 런타임 예외인 DataAccessExcption으로 포장해서 던져줌.
예외를 다른 것으로 바꿔서 던지는 예외 전환의 목적은 두 가지
JDBC 경우 DataAccessExcption으로 SQLException을 포장해주면서 좀더 상세한 예외정보를 제공해줌
연결 기능은 되지만 데이터를 엑세스 코드는 다 달라서 표준화되기 쉽지않음..?
유연한 코드를 보장해주지 못한다.
다양한 디비언어는 표준화되있지않는 코드를 제공한다.
해결방법은
DAO를 디비별로 만들거나
SQL을 외부로 독립시켜 바꿔 쓸 수 있게.
7장에서 좀더 자세히
디비마다 에러 종류와 원인도 제각각..
그래서 SQLExcption 하나에 모두 담아버림..
SQLExcption 하나에 모두 담아버리도록 설계
SQLExcption의 비표준 에러코드와 SQL 상태정보에 대한 해결책을 알아보자.
DB 전용 에러코드가 더 정확한 정보이므로.
일관성이 유지된다.
해결방법:
DB별 에러코드를 참고해서 발생한 예외의 원인이 무엇인지 해석하는
기능을 만들어 주면 됨.
디비 종류 상관없이 동일한 상황에 일관된 예외를 전달해야 효과적임
스프링은 DataAccessExcption의 서브클래스로 세분화된 여러 예외클래스가
있다.
스프링은 디비별 에러코드를 분류해 스프링이 정의한 예외클래스와 매핑해놓은 에러 코드 매핑정보 테이블을 만들어두고 이용함.
JdbcTemplate를 이용하면 JDBC에 발생하는 DB관련 예외는 거의 신경쓰지 않아도 됨
DAO를 굳이 따로 만들어서 사용하는 이유는?
데이터 엑세스 로직을 담은 코드를 성격이 다른 코드에서 분리해놓기 위해
전략 패턴을 적용해 구현 방법 변경해서 사용할 수 있게만들기위해
데이터 엑세스기술로 DAO 구현을 전환하면 사용 못함.
구현기술마다 예외가 다르기 때문에 메소드의 선언이 달라짐.
다행히 JDO , Hibernate , JPA등 기술은 SQLException 같은 체크 예외 대신 런타임 예외 사용 throw 선언 안해줘도 됨..
스프링은 자바의 다양한 데이터 엑세스 기술 사용시
발생하는 예외를 추상화해 DataAccessException 계층구조에 정리해둠
JPA JDO 하이버네이트 처럼 오브젝트/엔티티 단위정보 업데이트는
낙관적인 락킹 발생할 수 있음.
같은 정보를 두명 이상의 사용자가 동시에 조회하고 순차적으로 업데이트 할때
뒤늦게 업데이트 한것이 먼저 업데이트 한것을 덮어쓰지않게 막아주는 기술
스프링의 예외 전환 방법을 적용하면 기술 상관없이 DataAccessException 의
서브클래스로 통일가능
구체적으로 어떤예외가 발생했는지 확인해야된다.
JDBC 경우 위와 같은 듀플리케이트 익셉션이 던져지지만
다른 JPA 나 하이버네이트같은경우 다른 예외가 발생 한다.
DB에러 코드를 해석하는 JDBC 와 달리 JPA나 하이버네이트 등 각 기술이 재정의한
예외를 가져와 DataAccessException 으로 변환함
예외를 세분화 하지 않음
정리
예외를 잡아서 아무런 조취를 취하지 않거나 의미 없는 throws 선언을 남발 X
예외는 복구하거나 예외처리 오브젝트로 의도적으로 전달하거나 적절한 예외로 전환
좀 더 의미 있는 예외로 변경하거나, 불필요한 catch/throws를 피하기 위해
런타임 예외로 포장하는 두 가지 방법의 예외 전환이 있다.
복구할 수 없는 예외는 가능한 한 빨리 런타임 예외로 전환하는 것이 바람직하다.
애플리케이션의 로직을 담기 위한 예외느 체크 예외로 만든다.
JDBC의 SQLExcption은 대부분 복구할 수 없는 예외이므로 런타임 예외로 포장해야 한다.
SQLException의 에러 코드는 DB에 종속되기 때문에 DB에 독립적인 예외로 전환 될 필요가 있다.
스프링은 DataAccessException을 통해 DB에 독립적으로 적용 가능한 추상화된 런타임 예외 계층을 제공한다.
DAO를 데이터 액세스 기술에서 독립시키려면 인터페이스 도입과 런타임 예외 전환,
기술에 독립적인 추상화된 예외로 전환이 필요하다.