Nov 20th, 2012, 06:42 PM
Multithreaded job hangs on @Transactional methods
I have a simple spring batch job with one step.
- reads records from a database
- updates the records with an "in process" flag
- does some work
- updates the database
All the data access is via JPA.
This job works fine as a single-threaded job, but when I try to run multiple threads (by adding a SimpleAsyncTaskExecutor with throttle-limit > 1), the job hangs as soon as it encounters:
a) a method with a @Transactional annotation, or
b) an entityManager query in non-@Transactional methods.
It seems like spring is deadlocking while trying to bind the entityManager to a thread. We are using the same transactionManager and dataSource for the jobRepository and our business tables, which might be part of the problem.
Does anyone know what we are doing wrong?
Nov 27th, 2012, 10:55 AM
Where are you using the @Transactional annotations? From the use case you've described, I'd assume you're using all out of the box components which manage the transactions for you (aka no need for that annotation).
Nov 27th, 2012, 12:36 PM
It looks like the app had multiple transactionManagers defined against the same datasource -- one configured as part of the job set up (and with transactions managed by Spring batch), and another one with a different name defined in an imported context file (several imports deep). These were both configured to use the same dataSource object, so it was well and truly borked.
I've unwound this part of the mess, and the job is working now. However, it seems like the JPA access in the process portion is still contending for the shared entity manager, and isn't as parallel as I would like. Do I need to inject the EMF instead and manage my own separate entityManagers for each thread?
Tags for this Thread