Back End/Spring

[Spring] @Transactional 이 동작하지 않을 때

염소 2021. 9. 1. 21:17
반응형

■ 개요

Spring 에선 @Transactional 이라는 아주 놀라운 어노테이션을 제공한다.

트랜잭션을 쉽고 간편하게 사용할 수 있도록 추상화해놓은 어노테이션이다.

함수 머리위에 붙이기만 하면 내부적으로 트랜잭션 처리를 해 준다!

 

--> 라고 생각했지만 @Transcational이 구현되고 동작하는 방식을 모른 채로 

무작정 사용하면 원하는대로 동작하지 않는 경우가 많다.

 

이 글은 동작 방식을 설명하기 위한 것은 아니고,, 

내가 원하는대로 트랜잭션이 걸리지 않을 경우 검토할만한 것들을 정리해 보았다.

 

Spring에서의 @Transactional의 동작 방식은 아래 글을 참고하면 자세히 알 수 있다.

(본문과도 연관됨)

Spring AOP에서 Proxy란 ? (velog.io)

 

Spring AOP에서 Proxy란 ?

이전에 트랜잭션 관련 소스코드를 확인하던 중 트랜잭션을 적용한 메소드를 클래스 내부에서 실행 할때 this.method()가 아닌 전역변수에 self = TransactinoClass()를 생성해두고 self.method()로 호출한 코

velog.io

 

■ 본문

1.  @Transactional을 선언한 함수 내부에 try-catch구문

아래의 코드를 보자

public class FileService {

	@Transactional
	public FileBean selectFileInfo(String fileId) {
    	try {
        	//트랜잭션 처리할 함수
        } catch(RuntimeException re) {
        	//에러처리
        }
    }
}

트랜잭션을 선언한 함수 내부에 롤백할 코드를 try-catch 구문이 감싸고 있다.

의식의 흐름으로 코딩을 하다 보면 놀랍게도 이렇게 작성할때가 있다.

 

에러를 밖으로 던져야 하는데 내부적으로 잡아버리니 함수는 성공 처리된다.

성공으로 처리되기 때문에 트랜잭션이 롤백되지 않는다.

 

2.  @Transactional을 선언한 함수를 같은 클래스에서 호출할 경우

public class FileService {

	public void copyFile(String fileId) {
    	FileBean file = this.selectFileInfo(fileId);
        //....
    }

	@Transactional
	public FileBean selectFileInfo(String fileId) {
    	//select File
    }
}

 

 

@Transactional은 스프링 AOP기반으로 동작하기 때문에

같은 클래스 내부의 함수를 호출한 경우 동작하지 않는다.

 

자세한 내용은 위 개요의 velog 링크를 참고한다.

 

3.  @Transactional이 걸린 함수가 private인 경우

public class FileService {

	public void copyFile(String fileId) {
    	FileBean file = this.selectFileInfo(fileId);
        //....
    }

	@Transactional
	private FileBean selectFileInfo(String fileId) {
    	//select File
    }
}

사실 private 로 선언되었다는 것은 같은 클래스 내부의 함수에서 호출된다는 말이므로 위의 2번과 같은 내용이다.

 

4.  @Transactional이 걸린 함수 내부에서 CheckedException이 발생한 경우

public class FileService {

	@Transactional
	public FileBean selectFileInfo(String fileId) {
    	throw new IOException();
    }
}

위의 코드처럼 트랜잭션 내부의 클래스에서 IOException(CheckedException) 이 발생하면 롤백이 될까?

따로 설정을 하지 않았다면 롤백되지 않고 커밋이 될 것이다.

 

자세한 내용은 아래의 링크를 참고한다.

Checked Exception을 대하는 자세 - Yun Blog | 기술 블로그 (cheese10yun.github.io)

 

Checked Exception을 대하는 자세 - Yun Blog | 기술 블로그

Checked Exception을 대하는 자세 - Yun Blog | 기술 블로그

cheese10yun.github.io

 

■ 결론

@Transactional 어노테이션은 잘 사용한다면 매우 편하게 트랜잭션을 처리할 수 있다.

하지만 동작 방식이나 예외 사항이 있기 때문에 정확하게 알고 처리하는 것이 좋을 듯 하다.

 

복잡한 로직에 특정 부분만을 롤백처리 하고 싶다면

어노테이션이 아닌 선언적 트랜잭션으로 직접 처리하면 되겠다.

 

끝.

 

 

반응형