Skip to main content

Database Leak: getConnection() within Spring Transaction

I recently encountered an issue where one of my teammates was experiencing an issue where an application datasource would periodically become exhausted.  After discussing it a few times, we hypothesized that it was a situation where there was a database connection leak.  It was suspected the leak was within boundaries of some application code with a low call rate.  This would line up with, why the application would run for an extended period and then all of a sudden max out its database connections.

By inspecting the logs around the times of the database connection pool becoming exhausted it became pretty clear the potential location of the problematic code.

The cause of the issue was not a result of necessarily bad code writing, but more of a case of not knowing how legacy semantics would work within the context of a spring transactional boundary. The semantics of how a call to DataSource.getConnection() behaves within the Spring transaction boundary is probably not entirely evident.

The exact situation was even a little more confounded as the developer was actually calling a legacy API.  The legacy API had some interfaces defined to require a database connection to be provided. The API would perform some database activity and then expect the client/caller to perform connection maintenance and clean up.

The developer had a method within their application that was using a Spring annotation to mark it as transactional: 

@Transactional(propagation = Propagation.REQUIRED)

Note: Propagation.REQUIRED indicates that if a transaction is already initiated by a calling method then this method will participate in that transaction.  If one is not present, one will be created.

Within that method there was a call to retrieve a new database connection by calling getConnection on a datasource.  That call will always return a new database connection despite being within a transaction boundary and will never participate in the spring managed transaction.  Therefore if you use such a call you need to perform the standard database cleanup and close the connection after use.

However you could use the DataSourceUtils class from spring.  If you use the getConnection on the DataSourceUtils it will check if there is an active connection for the current thread.  If there is one it will utilize the active connection. If there isn't one then it will retrieve a new connection.  Of course you need to be careful with DataSourceUtils use as well.  If it leverages an active connection then no management of the connection is needed.  If it ends up creating a new one then that local logic should handle commit, rollback and clean up. 

Hopefully you will never need to mix legacy code within a more modern transaction context, but if you do run up against it, it is good to understand how it will behave.

Comments

Popular posts from this blog

HTML5 Canvas nightmares with JSF

The last couple of days have been one of those 'why is this so difficult' moments. I essentially lost more than a day trying to figure out how to get HTML5 canvases to show up in one of our JSF applications. Here is the background on the stack: JBoss AS 7.2.0 JDK 1.7.x Seam (JSF Framework) v2.2.0 Richfaces v3.3.3 Essentially we wanted to introduce a canvas to our page in order to graphical represent a numeric value and where it falls upon its normal range and possible range of values.   The page was leveraging a <ui:include> in order to display the results section.  It was a common component used among multiple pages and therefore the reason being pulled in via an include.  A richfaces commandLink was being used to initiate an AJAX request that would pull back none, one or many results and re-render the display within a JSF panelGroup.   Canvas Background:  If you look at any of the examples of using HTML5 canvases, you generally will see the definitio

WSO2: Simple Pass through proxy (REST to REST with HTML Reply)

Today I set out on trying to set up a simple passthrough proxy that would allow for a GET request to be made to REST style backend services that replies with HTML content. The proxy services was being set up on WS02 ESB v4.8.0.  I thought this was really going to be as simple as walking though their wizard and setting up a new proxy endpoint that just handed off to the behinds the scene service. It was straight forward to set up the proxy, but then unfortunately when called it just didn't respond. It took quite awhile to figure out what the issues was.  At first I was using the ESB admin console and review the System and Application Logs.  The Application Logs were certainly more useful, but they still truncated stack traces which made it hard to clue in on the real issue. It wasn't until I went and review the logs on the server that I was able to detect the cause.   <wso2_esb_root>/repository/logs/wso2-esb-errors.log 2015-03-19 16:09:43,001 [-] [Pass

Where to start on AngularJS for Java Developer

Background: If you are a Java developer who is comfortable using Eclipse (JEE Developer version) you may be asking yourself where to start with AngularJS. There is all kinds of documentation out there in regards to AngularJS and https://angularjs.org/ provides, to the point, tutorials on how to get started. You can certainly go that route and use node.js embedded server and possibly a Javascript focused IDE like WebStorm. However I wanted to try and stay in a comfort zone, my comfort zone, of Eclipse and be in a position to deploy an Angular application to a container like Tomcat. This blog entry will present the trail I took to try and accomplish it. Note: This is an adventure into Angular 1.x, not 2.x.  I would imagine this could all work with 2.x as well as it is focused on the dev environment setup. Start: Well the one consistent thing you will find to get started is to install the AngularJS Plugin, provided by Angelo ZERR.  You can use the Eclipse 4.5 (Mars) plugin inst