상세 컨텐츠

본문 제목

checked / UnChecked Exception / @Transactional rollback

Spring/Exception

by Chan.94 2022. 9. 13. 08:43

본문

반응형

Java의 예외는 크게 Error와 Exception으로 나눌 수 있다.

Error

에러는 시스템에 비정상적인 상황이 발생했을 경우에 발생한다.

예를 들어, 메모리 부족이나 스택오버플로우와 같이 복구할 수 없는 것을 말한다.
이러한 에러는 개발자가 예측하기도 쉽지 않고 처리할 수 있는 방법도 없습니다.

 

Exception

예외는 프로그램 실행 중에 개발자의 실수로 예기치 않은 상황이 발생했을 때를 말한다.

예를 들어 ArrayIndexOutOfBoundsException, NullPointerException, FileNotFoundException, IOException 등이 있다.

예외는 크게 Checked Exception와 Unchecked Exception로 나눌 수 있다.

 

chechekd Exception과 unChecked Exception 차이

  Checked Exception UnChecked Exception
처리 여부 반드시 예외처리 해야함 예외 처리 하지 않아도 됨
트랜잭션 Rollback 여부 Rollback X Rollback O
대표 Exception SQLException
IOException
ArrayIndexOutOfBoundsException
NullPointerException
FileNotFoundException 
확인시점 Complie Runtime

Checked Exception

RuntimeException의 하위 클래스가 아니면서 Exception 클래스의 하위 클래스들을 말한다.

반드시 예외 처리를 해야 하는 특징(try/catch or throw)을 가지고 있다.

 

UnChecked Exception

RuntimeException의 하위 클래스들을 의미한다. 예외 처리를 강제하지 않는다.

 

Code

@Service
@Transactional
public class TestService {
	
	@Autowired
	private TestMapper testMapper;
	
	public void checkedException(){
		...
		testMapper.insertTest(user);	//정상동작하는 SQL
		testMapper.sqlExceptionTest(user);	//SQL Exception
	}
	
	public void unCheckedException() {
		...
		testMapper.insertTest(user);	//정상동작하는 SQL
		
		throw new RuntimeException();	//RuntimeException
	}
}

unCheckedException은 아직 별도의 예외처리를 하지 않았기 때문에 insert문에 대해서 rollback이 진행되지 않는다.

checkedException은 RuntimeException이라는 예외를 발생시켰기 때문에 insert문이 rollback 된다.

 

트랜잭션 관리는 @Transactional 어노테이션을 사용하여도 되지만 Transaction AOP를 설정하여 관리하여도 된다.

Transaction AOP에 대한 내용은 Spring AOP Transaction설정 을 참고바란다.


예외처리 방법 1) rollbackFor

@Service
@Transactional
public class TestService {
	...
}

@Service
@Transactional(rollbackFor = {RuntimeException.class, Error.class})
public class TestService {
	...
}

@Transactional에는 rollbackFor 속성이 있다. rollback정책에 대한 값을 설정하는 속성이다.

rollbackFor의 default값은 RuntimeException과 Error에 대해서 rollback을 진행하도록 되어있다.

 

checked Exception까지 rollback을 하고 싶다면 rollbackFor 속성 값을 Exception으로 설정하면 checked Exception까지 rollback이 진행된다. Exception은 모든 Exception들의 최상위 클래스인 것을 잊지 말자.

@Service
@Transactional(rollbackFor = Exception.class, Error.class)
public class TestService {
	...
}

 

예외처리 방법 2) try ~ catch

@Service
@Transactional
public class TestService {
	
	@Autowired
	private TestMapper testMapper;
	
	public void checkedException(){
		try{
			...
			testMapper.insertTest(user);	//정상동작하는 SQL
			testMapper.sqlExceptionTest(user);	//SQL Exception
		catch (Exception e) {
			transactionManager.rollback();
		}
	}
}

unChecked Exception은 @Transactional 어노테이션만 달아준다면 rollback이 진행될 것이다.

앞선 설명과 테스트로 checked Exception은 자동으로 rollback이 진행되지 않는 것을 확인하였다.

 

try ~ catch구문을 통해 예외를 catch 하여 직접 rollback 해주어야 한다.

@Transactional과 try ~ catch구문을 같이 사용한다면 unChecked / Checked Exception 상관없이 직접 트랜잭션을 관리해주어야 한다.

 

@Transactional를 사용한다는 것은 DB 상태의 일관성을 지키기 위함이라 생각하면 된다.

try ~ catch를 사용한다는 것은 내가 클라이언트로 사용하는 어떤 컴포넌트에서 예외를 던질 수 있고, 나는 이것을 받아서 처리하겠다는 의미이다.

catch문에서 exception을 처리한 이후에 더 이상 exception이 전파되지 않기 때문에 rollback이 진행되지 않는다.

 

예외처리 방법 3) Custom Exception 처리

@Service
@Transactional
public class TestService {
	
	@Autowired
	private TestMapper testMapper;
	
	public void checkedException(){
		try{
			...
			testMapper.insertTest(user);	//정상동작하는 SQL
			testMapper.sqlExceptionTest(user);	//SQL Exception
		catch (Exception e) {
			throw new CommonMessageException(e);
		}
	}
}

2번 방법은 Exception을 catch한 후에 별도의 로직으로 예외를 처리하는 경우에 사용하게 될 것이다.

이때 선행된 트랜잭션에 대해서 rollback이 진행되지 않는 경우도 존재할 것이다.

하지만 대부분의 경우에는 rollback을 진행할 것이라 필자는 생각한다.

이때 매번 컨테이너에 있는 TransactionManager를 선언하여 관리하는 소스가 들어가야 한다. 이 부분을 간단하게 처리하는 방법이 Custom Exception이다.

 

CommonMessageException은 필자가 Custom 한 Exception 클래스이다.

RuntimeException을 상속받고 있어 rollback이 진행될 것이다.

 

공통 Expception 처리에 대한 내용은 공통 Exception 처리 포스팅을 참고 바란다.

반응형

'Spring > Exception' 카테고리의 다른 글

공통 Exception 처리 / Exception Message 처리  (0) 2022.09.14

관련글 더보기

댓글 영역

>