spring transaction manager and multithreading

spring transaction manager and multithreading  using -'java,spring,spring-transactions'

I am writing multithreading program in serviceImpl using Callable interface.I am using spring transaction manager.When update operation is executed in DB ,it is  executed successfully .But the updated data is not reflected in DB.But When i run program without multithreading it is updated in DB.

This is my configuration

<tx:advice id="txAdvice" transaction-manager="txManager">
            <tx:method name="*" />
            <tx:method name="find*" propagation="NOT_SUPPORTED" />
            <tx:method name="get*" propagation="NOT_SUPPORTED" />
        <aop:pointcut id="serviceOperation" expression="execution(* *..*ServiceImpl.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />
    <bean id="txManager"
        <property name="dataSource" ref="dataSource" />

I can shift to another approach for transaction manager.Just i want to get confirm if this approach supports or not  for multithreading.
So my question is
Do spring transaction manager supports multithreading(I mean just by declaring annotation  Or XML )
Why updated  data is not reflected in DB in my case?
What can be the best alternative approach ?

asked Oct 7, 2015 by vickeykumar66
0 votes

2 Answers

0 votes

You haven's show how you are doing multi-threading, so I can only guess what you have done:

In YourService.doSomething(), it createThreads. For each thread, it is doing DB related actions. Is that right?

As desecribed in another answer, transaction context is stored in thread local manner. Therefore, your logic in thread has no association with any transaction. One thing you can verify this is, apart from the logics in threads, in doSomething() you also do some DB actions. You will find that db actions you performed in doSomething() is committed while actions in threads are lost.

One of the reasonable way to solve is, normally we have a layer of application service which serves as a unit-of-work, and hence, we have transaction boundary on it (similar to your Service). Your thread should invoke the operations provided by the service. Of course, they will be all in different transaction.

If you want them all in one transaction, another way is, instead of let individual thread do the DB action, threads now do the heavy work and post the result back to the originated thread (by a producer-consumer queue for example). The originated thread is responsible to gather the result and perform DB actions.

Personally I would try to avoid manually passing the transaction context around different thread. This is simply ruining the whole idea of declarative transaction.

answered Oct 7, 2015 by abhimca2006
0 votes

The transactional context used by Spring is stored in a thread-local variable. So if you start a new thread, or execute code in another thread using a callable, this code won't be part of the transaction started by the Spring transactional aspect. That's why your data doesn't appear in the database.

answered Oct 7, 2015 by ashish singh