Announcement Announcement Module
No announcement yet.
Spring data + oracle AQ + glassfish Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring data + oracle AQ + glassfish

    I have a Spring 3 app in which I'm trying to to do database access (JDBC) and JMS (on AQ) via the same datasource so that local transaction suffices and no JTA/XA is required.
    The setup is working, in the sense that I can consume/produce messages and do database access via a single datasource: great!

    But, when I deploy it on Glassfish (2.1) I see that something withing spring is leaking the database connections.
    My pool is exhausted very fast (I have set max 100 connections).
    The datasource pool is setup with class: oracle.jdbc.pool.OracleDataSource and type javax.sql.DataSource.
    I did not enable any special wrapping (wrapping of metadata, statements etc.)

    My spring setup looks like this (I collected some of the relevant things here):

    <jee:jndi-lookup id="dataSource" jndi-name="jdbc/db" lookup-on-startup="false"
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" lazy-init="true">
    		<property name="dataSource" ref="dataSource" />
    <bean id="oracleNativeJdbcExtractor" class=""/>
    	<orcl:aq-jms-connection-factory id="connectionFactory" data-source="dataSource"  use-local-data-source-transaction="true"  native-jdbc-extractor="oracleNativeJdbcExtractor"/>
    First I thought it had something todo with the transaction manager.
    I used HibernateTransactionManager. But I was thinking that the DefaultMessageListenerContainer (which I use to auto consume messages) would for some reason not particapate in a transaction, so I switched to DataSourceTransactionManager.
    But that did not change at thing.

    If I look at how it works, I think that HibernateTransactionManager should be good enough.
    The DataSource that is used by the JMS infrastructure is wrapped in a TransactionAwareDataSource which uses DataSourceUtils to get its connection, and that is also what the hibernate connection factory is doing.
    Further more, if I debug, I see that the DataSourceTransactionManager is set on the DefaultMessageListenerContainer. Also, when a message is received in DefaultMessageListenerContainer:

    protected boolean receiveAndExecute(Object invoker, Session session, MessageConsumer consumer)
    			throws JMSException {
    		if (this.transactionManager != null) {
    			// Execute receive within transaction.
    			TransactionStatus status = this.transactionManager.getTransaction(this.transactionDefinition);
    			boolean messageReceived;
    			try {
    				messageReceived = doReceiveAndExecute(invoker, session, consumer, status);
    I can see that the TransactionStatus is there and its: newSynchronisation and newTransaction. I also see that the 'transaction' property points to an inner class of DataSourceTransactionManager (DataSourceTransactionObject)

    So everything should be good, but still the pool reaches 100 connections within a minute or so.

    What I have been thinking: does the unwrapping cause side effects?
    Because, if the datasource connection which is passed to AQ is unwrapped, how will the appserver know when for example 'close' has been called?
    Or does Spring call 'close' after the AQ did its job with the raw connection on the originally wrapped connection? Anyway some clues/insights would be appreciated!

  • #2
    If you use hibernate then you must also use the proper tx technology and that is HibernateTransactionManager, if you are leaking connections this is in general due to either improper tx setup (transactionamanger but no tx demarcation) or wrong hibernate configuration or messing around with sessions/connections yourself and not using the proper techniques to get them and participate in a spring managed transaction.

    However without the full configuration and maybe some db/hibernate code that is hard to say.