Transaction : DB에서 데이터에 대한 하나의 논리적 실행단계
ACID 원칙을 지킴
(원자성-Atomicity, 일관성-Consistency, 격리성-Isolation, 지속성-Durability)
커밋과 롤백
커밋(Commit)
롤백(Rollback)
클래스 레벨에서 @Transaction 적용
@Service
@Transactional
public class MemberService {
...
}
메서드 레벨에서 @Transaction 적용
특정 메서드에서만 @Transaction 적용 가능
클래스 레벨에서 Transaction에서 일부 설정 해야할것이 있다면, 메서드에 붙여 사용해서 적용가능 (메서드 레벨에 있는 설정 우선 참고)
@Service
@Transactional
public class MemberService {
...
@Transactional(readOnly = true)
public Member findMember(long memberId) {
return findVerifiedMember(memberId);
}
}
AOP 방식의 트랜젝션 적용
@Configuration
@RequiredArgsConstructor // 생성자 주입
public class TxConfig {
private final TransactionManager transactionManager;
@Bean
public TransactionInterceptor txAdvice() {
NameMatchTransactionAttributeSource txAttributeSource =
new NameMatchTransactionAttributeSource();
// 공통 트랜잭션 애트리뷰트
RuleBasedTransactionAttribute txAttribute =
new RuleBasedTransactionAttribute();
txAttribute.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
// 조회 메서드에 적용하기 위한 트랜잭션 애트리뷰트 ()
RuleBasedTransactionAttribute txFindAttribute =
new RuleBasedTransactionAttribute();
txFindAttribute.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
txFindAttribute.setReadOnly(true); // transaction 설정
// 트랜잭션을 적용할 메서드에 트랜잭션 애트리뷰트 매핑
Map<String, TransactionAttribute> txMethods = new HashMap<>();
txMethods.put("find*", txFindAttribute);
txMethods.put("*", txAttribute);
// TransactionInterceptor 객체로 만들어 넘겨줌
txAttributeSource.setNameMap(txMethods);
return new TransactionInterceptor(transactionManager, txAttributeSource);
}
@Bean
public Advisor txAdvisor() {
// pointcut을 이용하 타겟 클래스 지정
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("execution(* com.codestates.coffee.service." +
"CoffeeService.*(..))");
// 이후 인자를 넘김
return new DefaultPointcutAdvisor(pointcut, txAdvice());
}
}
체크 예외(checked exeption) Rollback 안됨
@Transactional(rollbackFor = {SQLException.class, DataFormatException.class})
Transaction 설정
readOnly = true (default false)
propagation
isolation (참고, 왠만하면 default 값을 사용)