Spring Boot | 데이터베이스 접근 | 선언적 트랜잭션 사용
선언적 트랜잭션 사용
- @Transactional 어노테이션을 메소드에 부여하면, 그 메소드 앞뒤가 트랜잭션 경계가 된다.
- 트랜잭션 경계 안에서 RuntimeException 및 그 서브 클래스가 throw 되면 트랜잭션은 롤백된다.
- @Transactional 어노테이션이 부여되어 있지 않으면, Exception 및 그 서브 클래스가 throw 되면 경우 롤백되지 않는다.
- Exception이 발생된 경우도 롤백되었으면 하는 경우는 @Transactional (rollbackFor = Exception.class)과 같이 설정한다.
코드 작성
src/main/java/sample/springboot/jpa/MyService.java
package sample.springboot.jpa;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
public class MyService {
@Autowired
private HogeRepository repository;
public void save(String value) {
Hoge hoge = new Hoge(value);
this.repository.save(hoge);
}
public void saveAndThrowRuntimeException(String value) {
this.save(value);
throw new RuntimeException("test");
}
@Transactional
public void saveAndThrowRuntimeExceptionWithTransactional(String value) {
this.saveAndThrowRuntimeException(value);
}
@Transactional
public void saveAndThrowExceptionWithTransactional(String value) throws Exception {
this.save(value);
throw new Exception("test");
}
public void show() {
this.repository.findAll().forEach(System.out::println);
}
}
src/main/java/sample/springboot/jpa/Main.java
package sample.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import sample.springboot.jpa.MyService;
@SpringBootApplication
public class Main {
public static void main(String[] args) throws Exception {
try (ConfigurableApplicationContext ctx = SpringApplication.run(Main.class, args)) {
MyService s = ctx.getBean(MyService.class);
s.save("normal");
try {
s.saveAndThrowRuntimeException("runtime exception without @Transactional");
} catch (Exception e) {}
try {
s.saveAndThrowRuntimeExceptionWithTransactional("runtime exception with @Transactional");
} catch (Exception e) {}
try {
s.saveAndThrowExceptionWithTransactional("exception with @Transactional");
} catch (Exception e) {}
s.show();
}
}
}
실행 결과
Hoge [id=1, value=normal]
Hoge [id=2, value=runtime exception without @Transactional]
Hoge [id=4, value=exception with @Transactional]
최종 수정 : 2017-12-17