You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Our application, based on Spring Boot 3.1.6 with latest Transaction Essentials 6.0.0, is connected to PostgreSQL 13.x.
Provided to us, Postgres instance has disabled prepared transactions (max_prepared_transactions set t 0).
Everything runs ok until a transaction rollback caused by transaction timeout, for example.
Atomikos then tries to execute "prepare transaction" statement on the connection even though we have only single resource (database connection) in the JTA transaction.
It's causing an exception in the driver as the prepared transactions are disabled:
2023-12-01 12:01:46.314 ERROR [6569bcc933d1962e4739abd7b1abb390] 1 --- [nerThread-52867] c.a.datasource.xa.XAResourceTransaction : XA resource 'dataSource': prepare for XID 'XID: 3139322E3136382E3133302E3130312E746D313730313432383434323635303130303235:3139322E3136382E3133302E3130312E746D313035363735' raised -7: the XA resource has become unavailable org.postgresql.xa.PGXAException: Error preparing transaction. prepare xid=XID: 3139322E3136382E3133302E3130312E746D313730313432383434323635303130303235:3139322E3136382E3133302E3130312E746D313035363735
at org.postgresql.xa.PGXAConnection.prepare(PGXAConnection.java:365) ~[postgresql-42.6.0.jar:42.6.0]
at com.atomikos.datasource.xa.XAResourceTransaction.prepare(XAResourceTransaction.java:304) ~[transactions-jta-6.0.0-jakarta.jar:na]
at com.atomikos.icatch.imp.PrepareMessage.send(PrepareMessage.java:40) ~[transactions-6.0.0.jar:na]
at com.atomikos.icatch.imp.PrepareMessage.send(PrepareMessage.java:19) ~[transactions-6.0.0.jar:na]
at com.atomikos.icatch.imp.PropagationMessage.submit(PropagationMessage.java:67) ~[transactions-6.0.0.jar:na]
at com.atomikos.icatch.imp.Propagator$PropagatorThread.run(Propagator.java:63) ~[transactions-6.0.0.jar:na]
at com.atomikos.icatch.imp.Propagator.submitPropagationMessage(Propagator.java:42) ~[transactions-6.0.0.jar:na]
at com.atomikos.icatch.imp.ActiveStateHandler.prepare(ActiveStateHandler.java:172) ~[transactions-6.0.0.jar:na]
at com.atomikos.icatch.imp.CoordinatorImp.prepare(CoordinatorImp.java:522) ~[transactions-6.0.0.jar:na]
at com.atomikos.icatch.imp.CoordinatorImp.terminate(CoordinatorImp.java:681) ~[transactions-6.0.0.jar:na]
at com.atomikos.icatch.imp.CompositeTransactionImp.commit(CompositeTransactionImp.java:279) ~[transactions-6.0.0.jar:na]
at com.atomikos.icatch.jta.TransactionImp.commit(TransactionImp.java:178) ~[transactions-jta-6.0.0-jakarta.jar:na]
at com.atomikos.icatch.jta.TransactionManagerImp.commit(TransactionManagerImp.java:428) ~[transactions-jta-6.0.0-jakarta.jar:na]
at com.atomikos.icatch.jta.UserTransactionManager.commit(UserTransactionManager.java:160) ~[transactions-jta-6.0.0-jakarta.jar:na]
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1026) ~[spring-tx-6.0.11.jar:6.0.11]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743) ~[spring-tx-6.0.11.jar:6.0.11]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711) ~[spring-tx-6.0.11.jar:6.0.11]
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:660) ~[spring-tx-6.0.11.jar:6.0.11
...
Caused by: org.postgresql.util.PSQLException: ERROR: prepared transactions are disabled
Hint: Set max_prepared_transactions to a nonzero value.
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2713) ~[postgresql-42.6.0.jar:42.6.0]
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2401) ~[postgresql-42.6.0.jar:42.6.0]
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:368) ~[postgresql-42.6.0.jar:42.6.0]
After investigation, we have found the problematic code in the CoordinatorImp class:
protectedvoidterminate ( booleancommit ) throwsHeurRollbackException,
HeurMixedException, SysException, java.lang.SecurityException,
HeurCommitException, HeurHazardException, RollbackException,
IllegalStateException
{
synchronized ( fsm_ ) {
if ( commit ) {
if ( participants_.size () <= 1 ) {
commit ( true );
} else {
intprepareResult = prepare ();
// make sure to only do commit if NOT read onlyif ( prepareResult != Participant.READ_ONLY )
commit ( false );
}
} else {
rollback ();
}
}
}
Participants count should be maximum one as we have only one database.
After debugging, we have found that an additional "fake" participant RollbackOnlyParticipant was added to the list to make rollback happen.
Therefore, the coordinator is treating this transaction as it had multiple resources.
In my opinion, rollback participant should not be considered as a normal resource.
Additionally, I've created a setup with Non-XA data source (and local-transaction-mode set to true) to avoid calling prepare statement. But still a simple rollback is causing strange warning and exception:
From AtomikosNonXAParticipant.prepare():
c.a.j.internal.AtomikosNonXAParticipant : com.atomikos.jdbc.AtomikosNonXADataSourceBean 'nonXaDataSource' [NB: this resource does not support two-phase commit unless configured as readOnly]
and error:
com.atomikos.icatch.RollbackException: Prepare failed because one or more resources refused to commit. This transaction has been rolled back instead. The cause could be either:
1. a transaction timeout (in which case you should see additional timeout warnings in this log file), or
2. inability to reach the resource (in which case you should see network errors), or
3. a resource-internal cause that we can’t inspect
at com.atomikos.icatch.imp.ActiveStateHandler.prepare(ActiveStateHandler.java:207) ~[transactions-6.0.0.jar:na]
at com.atomikos.icatch.imp.CoordinatorImp.prepare(CoordinatorImp.java:522) ~[transactions-6.0.0.jar:na]
at com.atomikos.icatch.imp.CoordinatorImp.terminate(CoordinatorImp.java:681) ~[transactions-6.0.0.jar:na]
Expecting here just a simple rollback of a timed out transaction.
The text was updated successfully, but these errors were encountered:
Our application, based on Spring Boot 3.1.6 with latest Transaction Essentials 6.0.0, is connected to PostgreSQL 13.x.
Provided to us, Postgres instance has disabled prepared transactions (max_prepared_transactions set t 0).
Everything runs ok until a transaction rollback caused by transaction timeout, for example.
Atomikos then tries to execute "prepare transaction" statement on the connection even though we have only single resource (database connection) in the JTA transaction.
It's causing an exception in the driver as the prepared transactions are disabled:
After investigation, we have found the problematic code in the
CoordinatorImp
class:Participants count should be maximum one as we have only one database.
After debugging, we have found that an additional "fake" participant
RollbackOnlyParticipant
was added to the list to make rollback happen.Therefore, the coordinator is treating this transaction as it had multiple resources.
In my opinion, rollback participant should not be considered as a normal resource.
Additionally, I've created a setup with Non-XA data source (and
local-transaction-mode
set to true) to avoid callingprepare statement
. But still a simple rollback is causing strange warning and exception:From
AtomikosNonXAParticipant.prepare()
:and error:
Expecting here just a simple rollback of a timed out transaction.
The text was updated successfully, but these errors were encountered: