Calling @Transactional methods from another thread (Runnable) Calling @Transactional methods from another thread (Runnable) spring spring

Calling @Transactional methods from another thread (Runnable)


The problem with your code is that you expect a transaction to be started when you call saveTaskResult(). This won't happen because Spring uses AOP to start and stop transactions.

If you get an instance of a transactional Spring bean from the bean factory, or through dependency injection, what you get is in fact a proxy around the bean. This proxy starts a transaction before calling the actual method, and commits or rollbacks the transaction once the method has completed.

In this case, you call a local method of the bean, without going through the transactional proxy. Put the saveTaskResult() method (annotated with @Transactional) in another Spring bean. Inject this other Spring bean into DemoService, and call the other Spring bean from the DemoService, and everything will be fine.


Transactions are held at thread local storage.
If your other method is running a thread with @Transactional annotation.
The default is set to REQUIRED and this means that if you run a method annotated with @Transacitonal from a different thread, you will have a new transaction (as there is no transaction held in the thread local storage of this thread).


Another option (besides creating separate Spring Bean with @Transactional method in it) is manually seting up transaction by using TransactionTemplate.

final TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);   taskExecutor.execute(new Runnable() {        @Override        public void run() {            transactionTemplate.execute(new TransactionCallbackWithoutResult() {                @Override                protected void doInTransactionWithoutResult(TransactionStatus status) {                   dao.update(object);                }            });        }    });