-
Notifications
You must be signed in to change notification settings - Fork 377
Description
Guillaume Polet opened DATAJDBC-94 and commented
Using a DefaultMessageListenerContainer with the attribute sessionTransacted set to 'true' and using a transactionManager ends up calling twice the method 'commi'. Once via the Transactional annotation support and a second time via org.springframework.jms.connection.ConnectionFactoryUtils.JmsResourceSynchronization.JmsResourceSynchronization which is registered as a TransactionSynchronization.
This synchronization is registered in the method org.springframework.jms.connection.ConnectionFactoryUtils.doGetTransactionalSession, and it implements the method afterCommit which eventually tries to invoke javax.jms.Session.commit().
Since the Session was created on top of the same connection as the one used by the TransactionManager, the TransactionManager will first perform its own commit on the connection and then the afterCommit of the TransactionSynchronization will itself also invoke commit on the JMS Session which delegates it eventually to underlying connection (but which is the same as the one used by the TransactionManager). This second is pointless and can even be quite dangerous because the underlying connection could be already released and re-used by another thread.
Background info where the issue happened:
- Using EclipseLink (and JPATransactionManager)
- Oracle JDBC driver v7
- Orale advanced queuing (with org.springframework.data.jdbc.config.oracle.AqJmsFactoryBeanFactory)
The way I spotted this is that, Oracle JDBC driver v7 enforces the fact that you cannot call "commit" on a connection with autoCommit = true. EclipseLink automatically set the autoCommit flag back to true whenever committing a transaction. Therefore JPATransactionManager was calling commit and setting back the autoCommit flag to true, and then the second commit was always triggering an Exception in Oracle driver
No further details from DATAJDBC-94