简体   繁体   中英

Java Batch Transaction Control

I have some code that used to run with bean managed transactions (my code would handle when to start or commit a transaction). This code was migrated to a container managed transaction and finally is used from within Java Batch (JSR-352 within Wildfly).

Now that the amount of data we process grows we see transaction-related problems. In various cases even a query fails, and the exception indicates the transaction is marked for rollback-only. So I assume some error must have happened during the migrations before.

I still want to go with container managed transactions, but...

  • how do I correctly use CDI in a batchlet so it receives an EntityManager? Do I use @PersistenceContext, @PersistenceUnit or @Inject annotations, or a combination?
  • how do I make use of a reasonable CDI scope? Looking at https://github.com/jberet/jberet-user-guide/blob/master/custom_cdi_scopes/README.md it occurs there are three scopes: Job, Step and Partition. As the batchlet I have runs for too long I probably need partition-scoped but how would the batchlet then control partitions?
  • I learned that reader/processor/writer pattern controls transactions ootb for chunk-amounts of records. Is that pattern applicable for code that reads a record, processes it and then immediately updates or deletes it?

Meanwhile I found the issue, and similarly to me posting a vague question I can now see that the answer was not easily concluded to my question.

My code used to run without container, so obviously it managed it's transactions on it's own. Later a container was added, and eventually I started writing code that used container managed transactions. But there was only one persistence unit, and it got configured for container-managed transactions. This seemed to be no problem for a long time until the data set grew.

The solution was for me to have two persistence units - one with and one without container managed transations: One is resource-local, the other JTA. My code needs to use the correct persistence unit so that transactions get managed properly.

You check out WildFly Quickstart for batch processing , which contains some useful examples of mixing batch, CDI and JPA, including injecting persistent context with @Inject .

For the use of various CDI scopes with JBeret, it depends on your specific use case. For most batch processing applicatins, they probably don't need to worry about it. But if you do find yourself need to control the scope of certain CDI beans, then choose the scope that fits the expected life cycle of the beans most.

If you want to immediately update it or delete it in your item writer, you can certaily choose item-count of 1. It's doable, but that will be less efficient.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM