My guess is that ServiceUser.method()
is itself transactional. It shouldn't be. Here's the reason why.
Here's what happens when a call is made to your ServiceUser.method()
method:
- the transactional interceptor intercepts the method call, and starts a transaction, because no transaction is already active
- the method is called
- the method calls MyService.doSth()
- the transactional interceptor intercepts the method call, sees that a transaction is already active, and doesn't do anything
- doSth() is executed and throws an exception
- the transactional interceptor intercepts the exception, marks the transaction as rollbackOnly, and propagates the exception
- ServiceUser.method() catches the exception and returns
- the transactional interceptor, since it has started the transaction, tries to commit it. But Hibernate refuses to do it because the transaction is marked as rollbackOnly, so Hibernate throws an exception. The transaction interceptor signals it to the caller by throwing an exception wrapping the hibernate exception.
Now if ServiceUser.method()
is not transactional, here's what happens:
- the method is called
- the method calls MyService.doSth()
- the transactional interceptor intercepts the method call, sees that no transaction is already active, and thus starts a transaction
- doSth() is executed and throws an exception
- the transactional interceptor intercepts the exception. Since it has started the transaction, and since an exception has been thrown, it rollbacks the transaction, and propagates the exception
- ServiceUser.method() catches the exception and returns