Commit data in multithreading only one time in Hibernate

I am persisting data using the EntityManager over multiple threads.
Each thread is commiting on finish, which should lead to inconsistent data.
So how can I say

  1. only the main thread should make the commit
  2. when any of the threads are failed, all data should be rolled back

Can I handle this by using ManagedExecutorService and passing the same UserTransaction through all threads?

Transactions are usually bound to a Java Thread, so you can’t pass around a UserTransaction. A database transaction also is “isolated” in some way, so if you want to implement some sort of synchronization between multiple transactions, you will have to implement this yourself.

Can I handle this by using ManagedExecutorService and passing the same UserTransaction through all threads?

What is “this”? You haven’t explained what you’re even trying to do. You can certainly generate data in multiple threads, but if you can’t partition the data in a way that every partition is independently useful/valid, then you will have to transfer that data to a single thread which will then do all the database interaction and commit.

So what I want to do in detail is:

I have two types of data.

  1. write first type by starting multiple threads

  2. after step 1, write second type using multiple threads because second type is dependent of first type.

The way why I am going parallelisation is, we have some triggers installed and it takes some time to run this.
So how can I ensure,

  1. the commit is made only once, although we have multipe threads using its own UserTransaction

  2. when any thread failed, all should be failed

private ThreadPoolExecutor executor;

public void writeObjects(List<Element> elements){
List<Future<Void>> fElements = new ArrayList<>();
for (Element el : elements) {
     fElements.add(executor.submit(() -> writeElement(el)));
}
fElements.foreach(f->f.get()));
}

public void writeElement(Element el) {
    ElementBusinessEntity ent = convert2BusinessEntity(el);
    entityManager.persist(ent);
    enitityManager.flush();
}

It should be possible that the main thread should manage the commitment?

It’s not possible. You can’t have multiple threads interact with the same JDBC connection as part of the same transaction.
Try isolating the work of the two steps into “partitions” so that every partition of work can be independently committed, only that way you can parallelize. Also, with parallelization you will ahve to forget about the atomic commit of the whole work. One thing you could do is to write to some temporary tables and drop old + rename the temporary tables in a post-step. That way you’d have atomic visibility of the data, but not sure if this is possible for you. Alternatively, you could insert into the main tables with some visibility flag or token set and in a post-step reset that column to make the rows visible to the rest of your application.