-
Bug
-
Resolution: Done
-
Blocker
-
8.0.0.Beta
-
None
-
False
-
None
-
False
-
-
-
-
-
-
CR1
-
-
Similar behaviour is already described in https://issues.redhat.com/browse/JBEAP-9730
Consider this scenario:
1) We have CMR datasource configured
2) We use this datasource to create a transaction
3) The connection to DB is unavailable for a brief moment (Simulated by injecting throw of SQLException to first call of java.sql.Connection.commit() )
4) I expect that the transaction should be rollbacked and the state of DB should stay unchanged
The step 4 seems not to happen. I can see that a rollback exception was thrown in server log, but the transaction is committed anyway.
The committed transaction seems to be caused by resetting the autoCommit property of connection in Ironjacamar, see: https://github.com/ironjacamar/ironjacamar/blob/main/adapters/src/main/java/org/jboss/jca/adapters/jdbc/BaseWrapperManagedConnection.java#L365
This behaviour seems to be same for all tested database drivers except MsSQL. I believe that this is due of MsSQL driver's implementation of endRequest method. See https://github.com/microsoft/mssql-jdbc/blob/d842883e3e69420a7a798294cb58ac252eead011/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java#L7197
This method resets the autoCommit property by itself and also rollbacks the connection if transaction was started. The reset of autoCommit by driver is also interesting in context of autoCommitOnCleanup property of Ironjacamar. For more info see: https://issues.redhat.com/browse/JBJCA-1431
It can be reproduced using little adjusted CMT quickstart
Steps to reproduce on postgreSQL:
Prerequisites:
- byteman installed
- byteman script "InjectFailureToCommit.btm" downloaded (Can be found in attachements) (This script injects the failure to java.sql.Connection.commit(), the rule is applied only the first time the method is called)
Adjust standalone.conf for JAVA_OPTS to include byteman JVM args (Replace paths with your path to byteman and provided script)
- -javaagent:/PATH/TO/BYTEMAN/lib/byteman.jar=script:/PATH/TO/SCRIPT/InjectFailureToCommit.btm,sys:/PATH/TO/BYTEMAN/lib/byteman.jar -Dorg.jboss.byteman.transform.all=true"
Start server:
- ./standalone.sh -c=standalone-full.xml
Configure server to use postgres CMR datasource using jboss-cli (use your paths and database connection info)
- module add --name=postgresql --resources=PATH/TO/DRIVER/postgresql-42.5.0.jar --dependencies=javax.api,jakarta.transaction.api
- /subsystem=datasources/jdbc-driver=postgresql:add(driver-name=postgresql, driver-module-name=postgresql, driver-class-name=org.postgresql.Driver)
- /subsystem=datasources/data-source=postgresDS:add(driver-name="postgresql",jndi-name="java:/postgresDS", connectable="true", connection-url="jdbc:postgresql://DB_URL:PORT/DATABASE_NAME",user-name="USER",password="PASSWORD")
- /subsystem=transactions/commit-markable-resource="java:/postgresDS":add(name=xids)
Add table to DB for the CMR
- CREATE TABLE xids (xid bytea, transactionManagerID varchar(64), actionuid bytea)
Deploy adjusted CMT QS
- git clone -b CMRCommitFailureReproducer git@github.com:OndrejGerzicak/quickstart.git
- cd quickstart/cmt
- mvn wildfly:deploy
Test the wrong behaviour
- Check list of customers (There is only Tom)
- Create customer (eg. John)
- Error appears (ignore the message of already existing user, that is just implementation of this QS that something went wrong. You can see in the log of server, that SQLException and also RollbackException was raised
- Check list of customer again. You can see that even though exception was raised and error appeared the customer is persisted in the DB.
- relates to
-
JBJCA-1467 Don't reset autoCommit on destroyed connections
- Resolved
-
JBEAP-24501 (7.4.z) JBJCA-1467 - Possible data inconsistency when CMR fails at Commit phase
- Closed
-
JBEAP-9730 Incorrect outcome when CMR fails at commit phase
- Reopened
-
WFLY-17802 Upgrade IronJacamar to 3.0.2.Final
- Closed