JAVA·Spring

@Transactional Checked Exception 사용시 Commit 되는 이유

무한열정 2024. 9. 4. 13:59

■ Java Exception 구성

Java에서 Exception(Checked)를 상속한 RuntimeException(Unchecked) 계열들이 파생된다.

* Java에서 설계적 관점 참고 글

https://velog.io/@eastperson/Java%EC%9D%98-Checked-Exception%EC%9D%80-%EC%8B%A4%EC%88%98%EB%8B%A4-83omm70j

 

■ Spring 기본설정

스프링 문서에 보면 Transaction의 기본 동작 설정은 Checked Exception(RuntimeException 계열 이외의 Exception)에 대해서 Comiit처리를 기본 설정값으로 안내하고 있다. (중요)
https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/rolling-back.html

 

Rolling Back a Declarative Transaction :: Spring Framework

You must carefully consider how specific a pattern is and whether to include package information (which isn’t mandatory). For example, "Exception" will match nearly anything and will probably hide other rules. "java.lang.Exception" would be correct if "E

docs.spring.io

In its default configuration, the Spring Framework’s transaction infrastructure code marks a transaction for rollback only in the case of runtime, unchecked exceptions. That is, when the thrown exception is an instance or subclass of RuntimeException. (Error instances also, by default, result in a rollback).

이는 스프링의 기본설정으로 실제 현업에서 사용시 적절해 보이지 않으며

모든 Exception에 대해 Rollback 처리를 위해서

다음 설정 중에서 선택적으로 추가하여 사용할 필요가 있다.

 

■ Checked Exception 발생시 롤백 처리

1) @Transactional 사용시 (rollbackFor={Exception.class} 속성 사용)

@Transactional(
    transactionManager = "txManager", // 트랜잭션 매니저 ID 지정
    rollbackFor = {Exception.class} // 이 예외가 발생하면 롤백
    //noRollbackFor = {RuntimeException.class} // 이 예외가 발생해도 롤백하지 않음
)

 

2) Java Config로 Transaction 설정시 ( RollbackRuleAttribute(Exception.class) 지정 )

private HashMap<String, TransactionAttribute> getRuleBasedTxAttributeMap() {
    HashMap<String, TransactionAttribute> txMethods = new HashMap<String, TransactionAttribute>();

    RuleBasedTransactionAttribute txAttribute = new RuleBasedTransactionAttribute();
    txAttribute.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
    txAttribute.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);
    txAttribute.setReadOnly(false);

    // Creating a list for rollback rules
    List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
    // Set to rollback when an exception occurs
    rollbackRules.add(new RollbackRuleAttribute(Exception.class));
    txAttribute.setRollbackRules(rollbackRules);
    txMethods.put("*", txAttribute);

    return txMethods;
}

 

3) XML로 Transaction 설정시 ( rollback-for="Exception" 지정 )

<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
        <tx:method name="*" read-only="false"
                              rollback-for="Exception"
                              propagation="REQUIRED"
                              isolation="DEFAULT"/>
    </tx:attributes>
</tx:advice>