Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
615 views
in Technique[技术] by (71.8m points)

java - @Transactional (noRollbackFor=RuntimeException.class) does not prevent rollback on RuntimeException

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

---service method below---

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

When dao.insert(e) in methodB() causes a primary key violation and throws a ConstraintViolationException, which is a subclass of RuntimeException, I would expect the transaction to still commit because of the noRollbackFor property I used. But I observed that the outer transaction (on methodA) is still being rolled back by the HibernateTransactionManager with the message

org.springframework.transaction.UnexpectedRollback Exception: Transaction rolled back because it has been marked as rollback-only

I've found similar questions reported but not exactly this one.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Once an exception is caught, the Hibernate Session should be discarded and the transaction should be rolled back:

If the Session throws an exception, the transaction must be rolled back and the session discarded. The internal state of the Session might not be consistent with the database after the exception occurs.

So, noRollbackFor applies to your Service and DAO layer that might throw an exception. Let's say you have a gatewayService that write to a Database through a Hibernate DAO and also sends an email through an emailService. If the emailService throws a SendMailFailureException you can instruct the gatewayService not to roll back when it will catch this exception:

@Transactional(noRollbackFor=SendMailFailureException.class)
public void saveAndSend(Entity e){
   dao.save(e);
   emailService.send(new Email(e));
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...