Transaction manager non-XA
I had configured a transaction manager in my mule-config file, however, I was not using XA-transactions, then I got this exception:
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Connection.close() has already been called. Invalid operation in this state.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.Util.getInstance(Util.java:381)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
at com.mysql.jdbc.ConnectionImpl.getMutex(ConnectionImpl.java:3018)
at com.mysql.jdbc.ConnectionImpl.commit(ConnectionImpl.java:1512)
at org.mule.transport.jdbc.JdbcTransaction.doCommit(JdbcTransaction.java:73)
at org.mule.transaction.AbstractTransaction.commit(AbstractTransaction.java:100)
at org.mule.transaction.AbstractSingleResourceTransaction.commit(AbstractSingleResourceTransaction.java:41)
at org.mule.transaction.TransactionTemplate.resolveTransaction(TransactionTemplate.java:172)
at org.mule.transaction.TransactionTemplate.execute(TransactionTemplate.java:107)
at org.mule.transport.TransactedPollingMessageReceiver$MessageProcessorWorker.run(TransactedPollingMessageReceiver.java:180)
The reason is that the JdbcMessageReceiver is always closing the connection if a transaction manager is configured, even if we are not dealing with xa-transactions:
JdbcMessageReceiver: ....
if (endpoint.getMuleContext().getTransactionManager() != null || tx == null)
{
// We are running in an XA transaction.
// This call is required here for compatibility with strict XA
// DataSources
// implementations, as is the case for WebSphere AS and Weblogic.
// Failure to do it here may result in a connection leak.
// The close() call will NOT close the connection, neither will it
// return it to the pool.
// It will notify the XA driver's ConnectionEventListener that the XA
// connection
// is no longer used by the application and is ready for the 2PC
// commit.
JdbcUtils.close(con);
}
Shouldn't there be a test that tests whether the tx is an xa-transaction (tx != null && !tx.isXA()) before closing the connection?
my config:
<jdbc:connector name="mysqlJdbcConnector" pollingFrequency="10000" dataSource-ref="mysqlDataSource">
<jdbc:query key="selectQuery" value="SELECT * from TABLE_A where FLAG='n'"/>
<jdbc:query key="insertStmt" value="INSERT INTO TABLE_B(VALUE) VALUES('y')"/>
</jdbc:connector>
<jbossts:transaction-manager />
<service name="simpleTest">
<inbound>
<jdbc:inbound-endpoint queryKey="selectQuery" connector-ref="mysqlJdbcConnector">
<jdbc:transaction action="ALWAYS_BEGIN" />
</jdbc:inbound-endpoint>
</inbound>
<component>
<prototype-object class="org.company.Service"/>
</component>
<outbound>
<outbound-pass-through-router>
<jdbc:outbound-endpoint queryKey="insertStmt" connector-ref="mysqlJdbcConnector">
<jdbc:transaction action="ALWAYS_JOIN"/>
</jdbc:outbound-endpoint>
</outbound-pass-through-router>
</outbound>
</service>
<spring:bean id="mysqlDataSource" class="org.enhydra.jdbc.standard.StandardDataSource" destroy-method="shutdown">
<spring:property name="driverName" value="com.mysql.jdbc.Driver"/>
<spring:property name="url" value="jdbc:mysql://localhost/myDB"/>
<spring:property name="user" value="user"/>
<spring:property name="password" value="pw"/>
</spring:bean>
I'm using mule-snapshot-2.0.3, mysql-connector-java-5.1.6-bin.jar