How to propagate Spring transaction to another thread?
I think the simplest solution would be configure the JobLauncher with a SyncTaskExecutor during test execution - this way the job is executed in the same thread as the test and shares the transaction.
The task executor configuration can be moved to a separate spring configuration xml file. Have two versions of it - one with SyncTaskExecutor which is used during testing and the other AsyncTaskExecutor that is used for production runs.
Although this is not a true solution to your question, I found it possible to start a new transaction inside a worker thread manually. In some cases this might be sufficient.
Source: Spring programmatic transactions.
Example:
@PersistenceContextprivate EntityManager entityManager;@Autowiredprivate PlatformTransactionManager txManager;/* in a worker thread... */public void run() { TransactionStatus tx = txManager.getTransaction(new DefaultTransactionDefinition()); try { entityManager.find(...) ... entityManager.flush(...) etc... txManager.commit(tx); } catch (RuntimeException e) { txManager.rollback(tx); }}
If you do want separate configurations, I'd recommend templating the isolation policy in your configuration and getting its value out of a property file so that you don't wind up with a divergent set of Spring configs for testing and prod.
But I agree that using the same policy production uses is best. How vast is your fixture data, and how bad would it be to have a setUp()
step that blew away and rebuilt your data (maybe from a snapshot, if it's a lot of data) so that you don't have to rely on rollbacks?