I'm testing a app which consist of hibernate and legacy jdbc is used together. I have a some spring testng test cases where i have TransactionAwareDataSourceProxy for managing transactions for legacy jdbc code under spring transactions which also update hibernate entities.

In my jdbc code i have special code segment which tried to unwrap the connection to get hold of the underlying connection to keep a mapping between some other information. This unwrapping behavior is implemented by calling the org.springframework.jdbc.datasource.ConnectionProxy.getTargetConnection method.

No my problem is when my code is inside a transaction and tries to call this unwrapping method that cause the TransactionAwareDataSourceProxy's invocation handler to get hold of the connection from the DataSourceUtils. This will increase the reference count at org.springframework.transaction.support.ResourceHolderSupport class. Since my unwrapping call doesn't close the connection after this getTargetConnection method call, my code ended up not decreasign the reference count at ResourceHolderSupport. At the end of the transaction when the connection is going to release through org.springframework.jdbc.datasource.ConnectionHolder#released. The holder will be still open since the reference count which was increased for unwrap operation was not decreased, this cause the actual connection to be kept open.

My datasource defintion looks as follows

    <bean id="myds" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy" autowire-candidate="true">
        <property name="targetDataSource">
            <bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
                <property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver" />
                <property name="url" value="jdbc:jtds:sqlserver://${server:localhost}:${port:1433}/${db.name};prepareSQL=2" />
                <property name="username" value="${db.user}" />
                <property name="password" value="${db.password}" />
                <property name="accessToUnderlyingConnectionAllowed" value="true"/>
            </bean>
        </property>
        <property name="reobtainTransactionalConnections" value="true"/>
    </bean>

The getTargetConnection will return the underlying connection which will not be aware of the transaction aware proxy. So incrementing the resource holder in such case will not receive a matching release since the returned connection might be closed by the consumer outside the transaction awareness.

In my app i only use the underlying connection to read catelog information which isn't causing any state change on the database side.

Comment From: gayanper

Updated the issue description

Comment From: snicoll

Unfortunately, it is very hard for us to confirm that the leak is in our code base given the details that you've shared. If you want us to investigate, please share a small sample that reproduces the problem. You can do so by attaching a zip to the issue or pushing the code to a separate GitHub repository.

Comment From: spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: gayanper

This was long time back I discovered it, and I don't work with that codebase anymore. So I'm closing this.