I've got a service (interface) that basically runs a bunch of modules in a readonly transaction and runs another set of them in a regular transaction. Via annotations I set up a JpaTransactionManager and marked the two methods as @Transactional.
All that worked fine, but due to the write transaction potentially taking a long time, i wanted to batch them. I updated the method that does the regular transaction by removing the @Transactional and wired up a transactionTemplate.
I didn't touch the other method (it's still marked as @Transactional)
Things sorta worked, but it's possible for the code to throw OptimisicLockingExceptions. In the code that can throw them (which is only being called by the method using the transactionTemplate) The client code is just eating those exceptions since that's the business case. When that happens, i get an exception saying:
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
After fiddling with that and trying to debug through all the proxies, i just removed the annotation based transactions and had my read only method just use the TransactionTemplate instead of the @Transactional and everything started working as expected.
It was my understanding that when using programmatic transactions, i control the rollbacks via catching exceptions and calling setRollBackOnly() It looks like some of the @Transactional magic was bleeding over into my other method. Is this expected? Are there ways around this or do I need to just pick programmatic or annotation based (at least in this class) and go with it.