본문 바로가기
언어/JAVA

[JAVA] 예외(Exception) 처리에 관한 고찰

by steadyMan 2022. 1. 22.

예외처리는 시스템안정성 및 오류현상 파악에 상당한 영향을 주는 아주 중요한 작업이라 생각합니다. 

 

시스템관리자에게 잘 처리된 예외상황은 시스템관리의 용이함을 증대시키기 때문입니다.

 

개인적으로 한번 꼭 정리하고 넘어가고 싶은 내용이라 정리하게 되었습니다. 

 

 

자바에는 크게 세종류의 예외가 존재한다. 

  • Error
  • Checked Exception
  • RuntimeException OR UnCheckedException

첫번째 Error을 제외하고 RuntimeException을 확장하지 않는 Exception은 모두 Checked Exception이다.

 

Throwable 계층도

1.Error 

Error란 컴퓨터 하드웨어의 오동작 혹은 JVM 실행에 문제가 생겼을 경우 발생

Error와 Exception의 차이는 애플리케이션 안에서 발생한건지, 밖에서 발생한건지 에 대한 차이가있다. 

애플리케이션에서 발생하는 오류가 아니며 시스템적인 문제가 원인이된다. 

ex) StackOverflowError, OutOfMemoryError

 

Checked, UnChecked Exception은 개발자의 코드에서 발생한다. 

2. Checked Exception

반드시 예외처리(try ~ catch OR throws Exception)가 강제되는 예외이다. 컴파일 시점에서부터 요구되며 

실행상황에 따라 발생가능성이 있는 예외이다.  처리가 강제되기에 개발과정에서 발견되어 실제 서비스 시점에 오류가 발생할 확률이 적다.

3. UncheckedException

Runtime Exception을 상속받은 예외로 처리가 강제되지 않으며 일반적으로 발생을 예측할 수 없고 복구할 수 없는 예외이다. 주로 개발자의 잘못된 로직 작성에 의해 발생하며 테스트가 제대로 되지 않았다면 실제 서비스시점에 

발생할 가능성이 높습니다. 발생할 확률이 높은 예외로  제일 주의해야하는 예외입니다.

 

위의 checked 와 unchecked의 차이를 아는것이 중요한데 이유는

트랜잭션(롤백 여부) 관리에 연관이 있기 때문이다.(너무 중요)

  Checked Exception Unchecked Exception
처리여부 예외 처리가 강제된다. 명시적 처리를 강제하지 않는다. 
확인시점 컴파일 단계 실행단계
예외발생 시 트랙잭션 처리 roll-back 하지 않음 roll-back 한다.
대표 예외 Exception 하위의 RuntimeException을
제외 한 모든 예외
  - IOException
  - SQLException
RuntimeException 하위 예외
  - IlleaglStateException
  - NullpointerException
  - IndexOutOfBoundException

Checked Exception발생 시 roll-back하지않고 commit 한다.

Unchecked Exception 발생시 roll-back처리한다.

 

기본적인 롤백여부의 규칙이 다르기 때문에 로직 작성시에 이를 인지하여 트랜잭션 처리를 할때에 

전파방식과 롤백규칙 들을 적절히 사용해야 한다. 

 

어떻게 처리하는 것이 좋을까?

각각의 상황에 따라 다르겠지만 공통적으로 로직 작성 시 생각해봐야 하는 예외 처리방법에 대해 생각해봤습니다. 

 

1. 무분별한 throws Exception 방지 

로직을 작성할 때 다양한 이유로 try~catch문을 작성하지 않고 예외처리를 미룹니다(throws Exception) 

이유가 있으면 무관하나 무분별한 throws는 상위메소드의 책임이 그만큼 증가되어 지양해야합니다.

 

2. 무성의한 try ~catch 처리

try/catch로 예외를 잡고 아무 조치도 하지 않는 것은 상당히 조심해야 한다.

예외가 발생하여도 무관하며, 다음 라인을 실행하겠다는 의도가 있는게 아니라면 반드시 피해야 한다.(이런 상황이 있을까 싶지만..)

이러한 코드는 오류가 있어서 예외가 발생했는데 그것을 무시하고 진행하는 꼴이므로 어떤 기능이 비정상적으로 동작하거나, 메모리나 리소스가 고갈되는 등의 문제를 야기할 수 있다. 그러므로 예외를 처리할 때에는 빈 값을 반환하는 등의 조치를 통해 상황을 적절하게 복구하거나 작업을 중단시키고 관리자에게 이를 전달해야 한다.

3. checked Exception의 예외전환

catch(SQLException e) {
   ... 
   throw new IllealStateException();
}

예외를 잡아서 다른 예외를 던지는 방식으로 호출한 쪽에서 어떤 예외 인지 명확하게 인지할 수 있도록 돕기위한

방법으로 Checked Exception을  UncheckedException으로 전환하여서

다른 계층에서 일일이 예외를 선언할 필요가 없도록 할 수도 있다. 

Checked -> Unchecked로 변경하는 전략은 try catch로 처리가 가능하고 이것의 이유가 명확하다면

try catch를 사용하는 것이 좋습니다. 하지만 그렇지 않은 경우가 더 많고 이때는 무의미한 try catch를 사용하는 것보다

Runtime Exception을 이용해 명확하게 메세지를 남기는 것이 더 좋은 방법입니다.

하지만 그러한 경우는 흔하지 않으며 Checked Exception이 발생하면 더 구체적인 Unchecked Exception을 발생시키고 예외에 대한 메시지를 명확하게 전달하는 것이 효과적입니다.

예시) 

try {
    // PK 중복으로 인한 SQLException 발생 
} catch(SQLException e) {
	throw new DupPrimaryKeyException(e.getMessage) // 커스텀 Exception을 발생시켜 직관적인 확인 가능
}

 2022-03-01 추가 내용

자바, 스프링강의로 유명하신 백기선님의 채널을 보다 자바의 예외처리관한 영상을 보게되었는데 스프링 프레임워크에서 예외 발생시에 트랜잭션 처리에 관한 이야기가 있었다. 

결론은 위 처럼 예외발생 시 Checked Exception은 DB 트랜잭션 roll-back하지않고

Unchecked Exception은 롤백한다는 사실은 잘못됐다는 것이다.

 

백기선님의 말씀을 나름대로 정리를 해보자면 예외발생 시 DB 트랜잭션 롤백처리여부는 직접 설정이 가능한데

이렇게 알고있는건 올바른 학습이 아니라는 말씀이다. 

 

실제로 담당하고 있는 프로젝트에서는 Checked Exception이 롤백이 되도록 설정되어있었다. 다만

디펄트 설정이 Unchecked일때 roll-back이기 때문에 다른 분들의 자료를 참고하여 작성하였는데

백기선님의 영상을 보고 이 내용을 추가 해야겠다 생각됐다. 

 

스프링에서 예외발생 시 DB 트랜잭션 롤백여부를 설정하는 방법을 작성해야겠다.

참조

https://mangkyu.tistory.com/152

https://cheese10yun.github.io/checked-exception

https://www.mkyong.com/spring-mvc/spring-mvc-exceptionhandler-example

https://www.nextree.co.kr/p3239

 

 

'언어 > JAVA' 카테고리의 다른 글

[JAVA] 캡슐화  (0) 2022.05.26
[JAVA] String, StringBuffer, StringBuilder의 차이점  (0) 2022.04.19
[JAVA] 메모리영역, static, 싱글톤  (1) 2021.02.25
[JAVA]자바 문자비교  (2) 2020.12.08
[JAVA] Arrays 클래스 사용  (0) 2020.12.08

댓글