Explicitly joining a JTA transaction requires a JTA transaction issue with jBPM 7 and Spring Boot - spring-boot

We use jBPM 7.41 business application with Oracle database. Under high load, transaction timeouts are detected and arjuna marks them for rollback. Then, jBPM executor thread reuse the same transaction and throws a repetitive exception "No active transaction...". The jBPM is working at the begining but after few minutes of work, there is no active JTA transaction. We use asynchronous executor with a simple command throwing exception, the processes execute normally but as soon as Arjuna Transaction Reaper cancels a transaction, the executor threads will throw the same exception "Explicitly joining a JTA transaction requires a JTA transaction".
We think that the same fix done for JtaTransactionManager in is needed for KieSpringTransactionManager.
We created a ticket here https://issues.redhat.com/browse/JBPM-9450 describing the problem and attached logs and a project to be able to reproduce it.
We tried several options, replacing Narayana with Atomikos and Bitronix, Oracle with PostgreSQL but the issue is the same.
It seems that we’re encountering the same problem described here: https://issues.redhat.com/plugins/servlet/mobile#issue/RHBPMS-4621.
Thank you in advance,
We use:
Spring Boot: 2.2.2.RELEASE
Kie Server: 7.45.0.Final
Narayana: 5.9.0.Final
Logs : https://issues.redhat.com/secure/attachment/12501068/logs.txt
Sample project to reproduce the issue available here: https://issues.redhat.com/secure/attachment/12501190/jbpm-perfs-oracle.zip

Related

JMS and JPA transactions without two phase commit (i.e. JTA is not supported)

I am migrating a Spring boot app running on a JEE app server which makes use of JTA to coordinate JMS and JPA transactions:
Exceptions raised while processing a message trigger a JPA and JMS roll-backs (i.e. message goes back to the originating queue)
If all database operations are successful, and, the message is successfully moved to the next queue, JPA and JMS transactions are both committed
The target environment does not support JTA.
I am looking for guidance on how to setup transaction managers so that:
a JPA transaction is started immediately after starting the JMS transaction
a JPA transaction is concluded just before terminating the JMS transaction
a failure of terminating the JPA transaction would fail the JMS transaction
Any documentation or sample code would be awesome.
Many thanks in advance
A possible way forward for this scenario where none of the resources support XA or JTA:
JMS provider
Database driver
... is to use a "bracketing" transaction manager configured to run two transactions. At high level, steps are as specified in Dave Syer's article
Start messaging transaction
Receive message
Start database transaction
Update database
Commit database transaction
Commit messaging transaction
The Spring Data project provides such a transaction manager: see ChainedTransactionManager .
This strategy works well when the error occurs in committing the database transaction, i.e. step 5. For cases where the error happens in the JMS commit, i.e. step 6, one will end up with the message in dead-letter.
Testing this implementation with 100,000 messages showed that about 0.005 % message end up in dead letter. For some, the error occurred when committing the JPA transaction, some for JMS.
For the system to be operable, messages in dead-letter should be retriable regardless of the point of failure. This means that the bracketing transaction manager option is only viable if the app is changed to implement idempotency: keep a trace of the JMS Message IDs already processed. The app has to skip the update part, step 4, for when the JMS Message ID was already processed.

Where does atomikos (JTA) keep its state?

TLDR:
1.Where does atomikos keep its trasnaction records so it can function and how is it best to "secure" them against losing/corrupting them. I use Docker/Docker-Compose and Spring Boot.
2.If the app dies unexpectdly, do all the transactions roll back because atomikos automagically started the appropiate SQL/JMS transactions with the sources?
Details
Hello.
I am starting to use atomikos in Spring Boot to enable XA transactions (in my case simply one datasource and an ActiveMQ/JMS broker.
I have been Googling and can't find a more "in depth" blog or site that explains in a bit more details how Atomikos works under the hood.
I do see the atomikos transaction logs in the form:
{"id":"127.0.1.1.tm159765570032300035","wasCommitted":true,"participants":[{"uri":"127.0.1.1.tm35","state":"COMMITTING","expires":1597655710327,"resourceName":"dataSource"},{"uri":"127.0.1.1.tm36","state":"COMMITTING","expires":1597655710327,"resourceName":"jmsConnectionFactory"}]}
I can only assume these are simply actual "logs" and not like the kafka.db file in say ActiveMQ when using file persistence.
Questions
So does atomikos keep its state in memory?
If say an unexpected shutdown occurred half way through an XA transaction, will all the JTA sources simply rollback?
If the atomikos state is held in a file/database somewhere...are there some best practices when using docker-compose for example?
Example:
A #Component picks out a database entity "REQUIRES_PROCESSING" for queuing on to a JMS queue and then switches the entity to "PROCESSING".
The JMS message is queued but then the App unexpectedly dies before the database entity is set to "PROCESSING".
Will in this case, atomikos has now no state (it died with the app) but it created a SQL and ActiveMQ trasnaction that will simply timeout and everything rolls back?
The application reboots 5 seconds later...what happens here? Is this transaction picked up again somehow (i.e. atomikos has still got state somewhere?).
Will the rebooted app just grab the rolledback entity and simply retry as expected?
Are there any pitfalls here?
Thank you for any claification.

Is it possible to wait transaction lock release with serializable isolation level?

Context:
We've built a JAVA application using spring framework (5.1.8) & spring boot (2.1.6) with the help of Jhipster.
It is a RESTFul application.
Data persistance is done in a PostGRES database managed by Hibernate (5.3.10).
Application constraints:
Because of our context, we have to process most of update transactions in the same order that they happen.
Problem:
All requests are processed by a business function declared as transactionnal (annoted with #Transactionnal(propagation=Propagation.REQUIRED)).
We set the isolation level to SERIALIZABLE to avoid execution of multiple transaction at the same time (concurrency).
However, with this isolation level, we have to manage the transactions repeat for case of concurrency exception.
Is there a way to force to wait transaction lock release before that isolation throws a concurrency exception (serialize access error), like with pessimistic locks ?
We tried to make transaction synchronized but it doesn't work because it seems commits are done outside the transactions.
Any help would be greatly appreciated.

Does Spring really gives new transaction for each thread?

I am working on a project which makes extensive use of spring transactions. I t so happened that i was throwing an exception AND NOT HANDLING IT PROPERLY which does not commit or rollback the transact Ion. So the connection remains active even when the thread is stopped. When new request to the web server ( Apache tomcat 7.0) comes the spring provides the earlier connection to the new thread. Since the thread didn't started the connection so the thread couldn't close it either ie .commit doesn't work. because of which the objects are not getting persisted in database in the consequent transactions even when there is no exception. How can i work around the problem so that i can detect where is the actual problem happening or can a design an exit point where i can explicitly close the transaction before response is sent to browser.
A runtime unchecked exception or error that is thrown from a #Transactional method will rollback that transaction by default; a return or a checked exception will commit the transaction by default. You can tell Spring to override that behaviour using the annotation type elements of the #Transactional annotation.
The Spring Framework reference manual has an entire chapter devoted to transaction management. You need to read and understand that as your starting point.

Websphere Scheduler

Websphere Scheduler is using scheduler datasource XA driver . When task is executed by scheduler it is starting a global transaction, but in our application we are creating a new connection to another database and explicitly commiting the data and closing the connection. This data source configured using non-XA driver datasource. For the application we have also enabled the Accept heuristic hazard (Last participant support extension) .
Now while running the scheudler we are getting the exception DSRA9350E: Operation Connection.commit is not allowed during a global transaction .
Can any one help me out in this
Your task runs in a transaction and probably you call commit in that transaction. So you should call your db operations, commit and close db outside that transaction.
Create bean-managed transaction session bean
#TransactionManagement(TransactionManagementType.BEAN)
and move db and transaction related code into the new bean.

Resources