0

we experience the following problem: We have got some service bean that does some handling and will iterate over a set and start an async thread for each entry, which will look like following:

@Service
public class ServiceBean {
  @Autowired
  private AsyncHandler asyncHandler;

  public void doService(Set<?> theSet) {
    for (Object obj : theSet) {
      Future<?> future = asyncHandler.doHandle(obj);
      // ...
    }
    // wait for all futures to complete
  }
}

@Service
public class AsyncHandler {
  @Async
  public Future<?> doHandle(Object object) {
    // dosth
    return future;
  }
}

Now we see that each thread will hold its own transaction and thereby database connection, which will cause the connection pool to run empty very fast.

What is the desired way to share the transaction accross all threads?

Thanks in advance!

Benny
  • 1,435
  • 1
  • 15
  • 33
  • 3
    You cannot. The transaction and connection is stored in a ThreadLocal. You cannot have a transaction span multiple threads. Limit the amount of concurrent threads you can have is the easiest solution. – M. Deinum Oct 26 '16 at 07:26
  • "You cannot"... I bet you can, maybe customizing Spring would be necessary. With the transaction in a ThreadLocal, there may be a possibility to get and set it in the new thread. – Benny Oct 26 '16 at 07:31
  • M. Dienum correct I've deleted my answer. – Essex Boy Oct 26 '16 at 07:38
  • 1
    Unless you are passing around connections and transactional state you cannot. You would need to reimplement the whole transaction strategy. With the out-of-the-box support you simply cannot achieve this. – M. Deinum Oct 26 '16 at 07:43

1 Answers1

5

What is the desired way to share the transaction accross all threads?

Don't do that. That makes it incredibly hard to understand what is going on. There's a reason why a transaction is attached to the thread that has created it. I guess your plan is to start all those asynchronous threads and then wait for them to complete to send the commit signal.

If you don't, who's going to complete the transaction? If a thread rollbacks the transaction, what happens in other threads that are still using it? You could pass the Connection around obviously but I'd expect things to be serialized anyway as most connection implementation are using synchronized in various places.

Stephane Nicoll
  • 31,977
  • 9
  • 97
  • 89