Cannot call Connection.commit in distributed transaction - java

I am using Weblogic 12c and I am getting the below error while committing distributed transactions in my application.
"java.sql.SQLException: Cannot call Connection.commit in distributed transaction. Transaction Manager will commit the resource manager when the distributed transaction is committed"
The part of code throwing exception is:
Session sessionNew = HibernateService.getService().getSession();
sessionNew.connection().commit();
This question has been asked several times, but the solution I am seeking is different.
The most common solution is to disable XA transactions to resolve the issue.
But my application contains more than resources like database, JMS etc.
Can anyone please suggest a solution other than the one mentioned above.
Also, I needed to understand if there is any relation between JTA transaction timeout value and the above-mentioned error.
Thanks a lot.

Most likely if you switch #TransactionManagement (TransactionManagementType.CONTAINER) to #TransactionManagement (TransactionManagementType.BEAN) this error will no longer occur.
So you define what you define when you commit, not the server.

Related

EclipseLink - ConcurrencyException - signalAttemptedBeforeWait

We've been working on an application that uses Tomcat 8 throught connection pool. We control Optimistic exceptions with #Version field, and we control transactions with Entitymanagers isolated by ThreadLocal.
However, the application triggers a concurrency exception sometimes with hangs other processes and requieres to restart the server.
The exception is always like this:
Caused by: Exception [EclipseLink-2004] (Eclipse Persistence Services - 2.6.4.v20160829-44060b6):
org.eclipse.persistence.exceptions.ConcurrencyException
Exception Description: A signal was attempted before wait() on ConcurrencyManager. This normally means that an attempt was made to commit or rollback a transaction before it was started, or to rollback a transaction twice.
at org.eclipse.persistence.exceptions.ConcurrencyException.signalAttemptedBeforeWait(ConcurrencyException.java:84)
at org.eclipse.persistence.internal.helper.ConcurrencyManager.releaseReadLock(ConcurrencyManager.java:468)
at org.eclipse.persistence.internal.identitymaps.CacheKey.releaseReadLock(CacheKey.java:475)
We've been trying to solve this problem or find any specific information about this error with no result. We even followed instructions in https://wiki.eclipse.org/EclipseLink/FAQ/JPA#How_to_diagnose_and_resolve_hangs_and_deadlocks.3F.
Disabling cache seems to solve the problem, but we cannt afford to not use cache due to performance needs.
Any help would be appreciated.
Thanks
Finally, after six months of headaches, I managed to solve the problem.
The general error was EclipseLink-2004. If you check Eclipselink error reference:
Eclipse link error reference page, it says "Verify transactions in the application".
I've been using a application managed Entity Managers. To control that transactions were single-thread I used this ManagerHelper class:
EntityManagerHelper
The problem was that I was putting a managed object inside a Session attribute. I don't really understand the process inside, but somehow it created new transactions outside the main transaction if it was used to query. Moving the object to Request attributes solved the problem.
I hope this helps to someone in the future.
Best regards

The End of XA-Transaction, Garbage Collection and till-tx-complete =true

Having the following problem of understanding why a connection session exists that goes on for 6 hours and also holding a lock and breaking the thread the question is rased if a connection of XADataSource (Oracle driver) needs a Java reference at all to be kept alive.
In terms of distributed transaction set to kept till it is explicitly ended (keep-xa-conn-till-tx-complete=true) I wonder how a driver could decide wether to close connection and commit a transaction once the GC recycled the connection. Is there even a way for the DBMS to do so?
So the question goes how does a DBMS decide wether to abandon a distributed transaction or not.
The DBMS does not decide to end the transaction, the transaction manager does.
The transaction manager is set up to run in your application containers, whether they are Spring, J2EE application servers, or something else. They have to "know" they are distributed transaction managers by being configured correctly. In a distributed transaction environment, where you have multiple transactional applications and/or services interacting to complete a transaction, they must all be able to support distributed transactions to make proper use of the XADataSources and send the right signals up and down the chain for commit vs rollback.
Presuming that you have the above situation, multiple applications and/or services participating in a distributed transaction, it sounds as if one of them is not configured correctly. Something in the chain is not truly a distributed transaction, so that when it completes it's only completing locally and not sending the signal back down the line. So the distributed transaction never completes, holding the connection open.
Check the configuration of every application and/or service participating in the transaction. Add logging output on each that details whether the transaction is a distributed one or not. If you can't do that, then dd logging output to each that records the start and end of the transaction. Find the latest point in the sequence of actions where you see an open-transaction but not a close-transaction. If you see that, it's likely the node right after it in the chain that is doing something wrong.
Good luck.

jdbc connection error: not associated with a managed connection

My application is trowing the following exception:
java.sql.SQLException: Connection is not associated with a managed connection.org.jboss.resource.adapter.jdbc.jdk6.WrappedConnectionJDK6#4fe91321
This is happening in production I'm not able to get this problem in development and for that I'm not able to solve it.
The root of the exception is code line dbConn.prepareStatement(sql);
From what I was able to find in the web, the cause for this can be:
Over jdbc connection, a jboss connection is wrapped but the wrapper is empty. The original jdbc connection inside is no longer there.
JDBC Connection is already closed and trying to work with close connection is the reason why I'm getting this exception.
The transaction manger detects transaction that is taking to long then the transaction timeout.
So if someone can point me what is the problem because I'm not able to get this problem in mine development environment.
Also what logs can I add that will help me detect the problem in production - I'm using Java, JBoss, Postgre.
I'have enable connection close monitoringa, and also to add is that the issue is not consistent
I just resolved the issue.
It's my jndi driver not compatible with the latest java frameworks.
I'm using Oracle db and ojdbc6, and i download a latest ojdbc6 from maven repository and replace the old same name jar file. It works like bird now.
If you are using an EJB, it's possible that your Stateless Session Bean Pool is not big enough. The connection can't find an associated thread.
Maybe you have an extended Transaction for a not Stateful Session Bean, wich is maybe not a good idea.

Spring Transaction Synchronization of JDBC and JMS

I have a spring web app running on jboss that is currently configured to use the HibernateTransactionManager for db transactions and the JmsTransactionManager for jms. For jms we use Camel and ActiveMQ, our database is DB2. Within a transaction I need to write a number of records to the database and send two asynchronous jms messages. The jms messages are event notifications and I only want them to be sent if the database transaction commits.
I am willing to accept the risk of the communication with the broker failing after the jdbc transaction has already committed (and thus no messages sent but db committed) so I do not think I need proper XA.
I believe that what I need is "best efforts" transaction management using spring transaction synchronization.
The spring documentation sort of hints at the fact that spring will synchronize the two transactions and commit the jms transaction only after the jdbc transaction has been committed - but I don't think it is very clear. The spring documentation here http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#tx-resource-synchronization doesn't go into enough detail about how it works.
I have found a couple of other sources that say spring will do what I want including some javadoc below, and I have written some integration tests that also show it.
http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/jms/support/JmsAccessor.html#setSessionTransacted%28boolean%29 The javadoc on setSessionTransacted here sounds like exactly what I want.
From what I have seen I think creating the Camel JmsConfiguration with transacted set to true like this is enough:
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="pooledConnectionFactory"/>
<property name="transacted" value="true"/>
<property name="concurrentConsumers" value="10"/>
</bean>
However I need to convince someone I work with who is a bit skeptical and thinks that my integration test only works because of a poorly documented side effect rather than a intentional spring feature.
So my question is - Am I correct that spring can be relied upon to synchronize the transactions and always commit the jms transaction after the jdbc transaction or is that not something that I should rely on, and could you point me at any official documentation that says that clearly? And I guess in general is this a good approach to take or should we be managing these transactions in a different way?
This article might be of help Distributed transactions in Spring, with and without XA. I don't think it covers your case specifically - sending message + updating database.
Official Spring Boot repository contain JTA examples that combine JMS with JDBC based on Atomikos, Bitronix or Java EE server JBoss WildFly.
Additionally I also created few examples that are located in my Github repository. This contains also non-Spring Boot (pure Spring) example.
If you are using Local transactions
And the usecase is save to database and then send to jms
Then there could be three cases :
Exception just after receiving(before DB and JMS)
No problem everything will be rolledback
After saving to DB , we have exception
If there is an insert operation,there will be mutiple rows in DB due to retries.With each retry , an insert will be done.And for JMS , message will go to DeadLetterQueue
After saving to DB and sending to JMS , we have an exception
If there is an insert operation,there will be mutiple rows in DB due to retries.With each retry , an insert will be done.And for JMS , message will go to DeadLetterQueue
Now you dont want to use XA, so the solutions could be
1)Check If(message.getJmsRedelivered() {…}
If not , process it
If its redelivered , check if you processed it already
Check if the data is in database based on details in message
Note that re-deliveries are rare so , this check is also rare and there is no overhead
2)If your method is idempotent , then you dont need this check
And regarding XA , XA guarantees that message is delivered only once
And synchronize the transaction across multiple resources
But with XA , you have overhead
So if you can manage without XA , it is preferable

How to assert that database connection is in a transaction?

I'm using an object/relational mapper to talk to the database. The library in my case is iBatis which is also used for transaction management.
However, I recently had a case where iBatis didn't actually start a transaction even though startTransaction() etc. was called as documented.
After some debugging I found out that there was a configuration mistake on my side.
One might blame iBatis but I would like to avoid such misconceptions in the future.
So here's the question:
How can I programmatically assert that the current database connection is running in a transaction?
The databases I'm using are Oracle, MySQL and H2 (for testing).
I'm not 100% sure if this is absolutely indicative of being in a tx, but Connection.getAutoCommit() tells you if the connection is in auto-commit mode, where auto-commit "on" means "no transaction".
There may well be cases where this assertion does not hold, but most JDBC-based frameworks will use that setting to control transactions.

Categories