Gab Gab - 2 months ago 26
Java Question

Global transaction management - Jboss : Closing a connection for you

We have a spring application deployed on a jboss 7 server.

The application uses multiple datasources obtained from jboss through jndi.

The Transaction management is also provided by the Java EE container (we use Spring JtaTransactionManager)

The app architecture is a legacy one with DAOs extending hibernate Templates (using Spring HibernateDaoSupport).

Transaction are managed in the service layer using

@Transactional
annotations.

My 1st questions are:


  • when encountering the annotation, how does the transaction manager know which datasources will be involved in the transaction ?

  • when does it effectively retrieve a JDBC connection and on which datasources ? when does it effectively open a transaction ?
    (only DAOs got a reference to the sessionFactory bound to a specific datasource).



The driver we are using does not support distributed (XA) transactions, in most case we doesn't need multi-phase commit as only one datasource is written. Anyway when we access (read only) other datasources within the same transaction we got messages in logs :

INFO [org.jboss.jca.core.api.connectionmanager.ccm.CachedConnectionManager] (http--0.0.0.0-8080-4) IJ000100: Closing a connection for you. Please close them yourself: org.jboss.jca.adapters.jdbc.jdk6.WrappedConnectionJDK6@691644c: java.lang.Throwable: STACKTRACE
at org.jboss.jca.core.connectionmanager.ccm.CachedConnectionManagerImpl.registerConnection(CachedConnectionManagerImpl.java:265)
at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.allocateConnection(AbstractConnectionManager.java:495)
at org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:129)
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:81) [spring-orm-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
[...]



  • Is there a way to properly manage connection release in such a case without using XA datasources ?

  • Otherwise can those message safely be ignored or do they denote a real problem ? (log level is INFO)



[edit]

Some additional data on configuration :

exemple of datasource declaration

<!-- JNDI datasource -->
<bean id="customersDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/${shared.datasource}" />
</bean>


Associated sessionFactory

<bean id="sharedSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="customersDataSource" />
<property name="configLocation" value="classpath:hibernate.shared.cfg.xml" />
<property name="hibernateProperties">
<props>
<!-- jboss specific transaction management -->
<prop key="transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>
<prop key="transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</prop>
<prop key="hibernate.connection.release_mode">after_transaction</prop>
<prop key="hibernate.transaction.auto_close_session">true</prop>
[...]
</props>
</property>
</bean>


We are thinking about playing with
hibernate.connection.release_mode
but even if only one datasource is actually written within a single transaction, it's not always the same one.

Gab Gab
Answer

Well I was making a mountain out of a mole hill.

In fact some access to datasource are outside of a transactional scope, as the hibernate connection release mode is set to after_transaction connection is never released.

I just added some missing @Transactional annotations and it fixed the problem.

Note than it seems that a propagation set to support seems to trigger the connection release even when the caller is not inside a transactional scope

Comments