복붙노트

[SPRING] @Transactional (noRollbackFor = RuntimeException.class)은 RuntimeException에서 롤백을 방지하지 않습니다.

SPRING

@Transactional (noRollbackFor = RuntimeException.class)은 RuntimeException에서 롤백을 방지하지 않습니다.

@Transactional (noRollbackFor=RuntimeException.class)
public void methodA (Entity e){
   service.methodB(e);
}

--- 아래 서비스 방법 ---

@Transactional (propagation=Propagation.REQUIRES_NEW, noRollbackFor=RuntimeException.class)
public void methodB (Entity e){
   dao.insert(e);
}

methodB ()의 dao.insert (e)가 기본 키 위반을 일으키고 RuntimeException의 하위 클래스 인 ConstraintViolationException을 던지면 내가 사용한 noRollbackFor 속성 때문에 트랜잭션이 여전히 커밋되기를 기대합니다. 그러나 (methodA의) 외부 트랜잭션이 여전히 메시지와 함께 HibernateTransactionManager에 의해 롤백되고있는 것을 관찰했다.

나는 이와 비슷한 질문을 발견했지만 정확한 것은 아닙니다.

해결법

  1. ==============================

    1.예외가 잡히면, Hibernate Session은 파기되어야하고 트랜잭션은 롤백되어야한다 :

    예외가 잡히면, Hibernate Session은 파기되어야하고 트랜잭션은 롤백되어야한다 :

    noRollbackFor는 예외를 던질 수있는 서비스 및 DAO 레이어에 적용됩니다. Hibernate DAO를 통해 데이터베이스에 쓰고 emailService를 통해 이메일을 보내는 gatewayService가 있다고 가정 해 보겠습니다. emailService가 SendMailFailureException을 throw하면 gatewayService가이 예외를 catch 할 때 롤백하지 않도록 지시 할 수 있습니다.

    @Transactional(noRollbackFor=SendMailFailureException.class)
    public void saveAndSend(Entity e){
       dao.save(e);
       emailService.send(new Email(e));
    }
    
  2. from https://stackoverflow.com/questions/27849968/transactional-norollbackfor-runtimeexception-class-does-not-prevent-rollback by cc-by-sa and MIT license