4

My objective is to provoke an optimistic locking exception in my application using a unit test. I already have a understanding on how to do this in theory. But my problem in practice is how do I maintain a transaction between two threads ?

So, this is what I've done so far:

I am using a JUnit test with:

@RunWith(SpringJUnit4ClassRunner.class)

using EntityManager org.springframework.orm.jpa.JpaTransactionManager

where each method is defined @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)

and start a transaction with entityManager.getTransaction().begin(); and end with entityManager.getTransaction().rollback());

This works great, saving, updating etc in single threaded tests.

To create multiple threads I use Springs TaskExecutor (similiar to what's desribed here: Any good Spring threading with a TaskExecutor examples?)

But what do I have to do to maintain the transaction between the two threads? I've tried stuff like annotating the run()-method with @Transactional but this doesn't work.

Community
  • 1
  • 1
Peter
  • 5,556
  • 3
  • 23
  • 38
  • 3
    The transactional context is maintained in ThreadLocal and in general not propogated across multiple threads. – Aravind Yarram Oct 25 '12 at 13:55
  • Any suggestion on alternatives? – Peter Oct 25 '12 at 13:55
  • 1
    may be if you use container managed threads (like websphere workmanaer), the container might propogate the contexts across thread. i am not sure just thinking out loud. – Aravind Yarram Oct 25 '12 at 13:59
  • Is this similar to what you're trying to do? http://stackoverflow.com/questions/2455794/unit-testing-hibernates-optimistic-locking-within-spring – MarkOfHall Oct 26 '12 at 15:19

1 Answers1

6

Few questions that come to mind -

Global Transaction
Should all of your threads be part of the same transaction? The implications are that, if a thread throws an exception, do you want to rollback changes in other threads?

Local Transaction Should each thread have it's own transaction boundary with out affecting other threads? In this case, the exceptions and rollbacks in one thread do not affect other threads.

To achieve global transactions, you will most likely have to use a JTA transaction manager with appropriate resource drivers. Spring does not have default support for global transactions. If your application is running in a Java EE application server (Jboss, Weblogic), you get JTA support by default and you could configure spring to use your application server's transaction management capabilities. If you are running in tomcat, you could plugin an open source JTA implementation like -

Atomikos

Jboss Transactions

To achieve local transactions (i.e., each thread with it's own transaction boundaries), I don't think you will have to do anything more than use spring transactional annotations. In the following example, just make sure that 'service' is a spring bean and doSomething() is appropriately annotated.

taskExecutor.execute( new Runnable() {
           public void run() {
                service.doSomething( );
           }
      });
Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
Sashi
  • 1,977
  • 16
  • 15
  • 1
    lets talk about first one (global transaction) when I am using weblogic. How should I configure taskExecutor to use global transaction – hudi Aug 25 '16 at 10:03