2016-08-11 2 views
0
@Transactional 
public void foo(){ 
    doSomthing(); 
    try{ 
     bar(); 
    }catch(BizException e){ 
     logger.warn("call bar failed",e); 
     // do some work here 
    } 
    doSomethingElse(); 

} 
@Transactional 
public void bar(){ 
    // ... 
    if(meetSomeCondition){ 
     throw new BizException(...); 
    } 
    // ... 
} 

바 던져 BizException가 명시 적으로 예외를 잡기도 foo는에, 마지막에 여전히 롤백하고 예외내부 메서드 만 롤백하고 외부 메서드에 영향을주지 않는 방법은 무엇입니까?

org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:720) 

아래로 던져 그리고 몇 가지 해결책이있다하지만 난 그게 내 상황

에 대한 가능한 아니라 발견하는 경우

예 :

@Transactional(noRollbackFor=BizException.class) 

BizException을 던져이 경우에는 롤백해야 foo에 있기 때문이다.

@Transactional(propagation=Propagation.REQUIRES_NEW) 
public void bar() 

명시 적으로 전파를 지정하는 경우

는 새로운 세션을 생성 만이 세션을 롤백합니다 전화 bar() REQUIRES_NEW이다. 그러나 바가 실패하면 다른 프로세스가 롤백됩니다.

그래서 지금 내 임시 방편 내가 직접 anotherBarWithoutTransaction를 호출합니다 내 위의 경우

public void anotherBarWithoutTransaction(){ 
    // ... 
    if(meetSomeCondition){ 
     throw new BizException(...); 
    } 
    // ... 
} 

@Transactional 
public void bar(){ // only add an annotation 
    anotherBarWithoutTransaction(); 
} 

입니다. 그러나 그것은 이상적이지 않습니다.

답변

0

프로그래밍 방식의 트랜잭션 관리 방법을 사용하여 새 트랜잭션을 명시 적으로 생성하십시오.

@Autowired 
private TransactionTemplate transactionTemplate; 

transactionTemplate.execute(new TransactionCallbackWithoutResult() { 
    protected void doInTransactionWithoutResult(TransactionStatus status) { 
     try { 
      barService.bar(); 
     } catch (ApiException e) { 
      logger.warn("call bar failed",e); 
      status.setRollbackOnly(); 
     } 
    } 
}); 

<bean id="transactionTemplate" 
     class="org.springframework.transaction.support.TransactionTemplate"> 
    <property name="propagationBehaviorName" value="PROPAGATION_REQUIRES_NEW"/> 
    <property name="transactionManager" ref="txManager"/> 
</bean> 

은 참조 : http://docs.spring.io/autorepo/docs/spring/4.2.x/spring-framework-reference/html/transaction.html#transaction-programmatic