My Spring/Java web application has @Transactional
services that can touch the database:
@Transactional
public class AbstractDBService { ... }
Desired functionality is for any uncaught throwable that propagates up beyond the service layer to cause a rollback. Was a bit surprised this isn't the default behaviour but after a bit of googling tried:
@Transactional(rollbackFor = Exception.class)
This seems to work except when an exception is deliberately swallowed and not rethrown. (The particular case is when an entity is not found. Guess this could be redesigned to not throw an Exception but expect there will inevitably be others - e.g. one that springs to mind is an InterruptedException
when using Thread.sleep()
). Then Spring complains:
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly ...truncated.. Caused by: javax.persistence.RollbackException: Transaction marked as rollbackOnly at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:58) at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
Am I missing something here?... Is there a way to tell Spring to rollback on all uncaught throwables?