Atomikos Forum

transaction manager not releasing connections?

OK, we have started experimenting with atomikos and we are experiencing a quite funky issue.

Basically, we have a method that uses the AtomikosTransactionManager. it calls another class that does database stuff using a datasource configured with that manager.

What we saw was that if the method throws an exception, for example because of invalid SQL, the data source kept the connections and we run out of connections eventually.

the main method:
try {
            tm.begin();
            for (int i = 0; i < sourceInstanceList.size(); i++) {
                SourceTypeImplementation sti = sourceTypeImplementations.get(i);

                Object data = sti.getSourceData(sourceInstanceList.get(i));
                sourceDataList.add(data);
            }
        } catch (Exception e) {
            logger.error("processSources;" + e.toString(),e);
            throw new TransformException(TransformExceptionCause.SOURCE_DATA, e, "processSources");
        } finally {
            try {
                tm.commit();
            } catch (Exception e) {
                logger.error("processSources;commiting transaction;" + e.toString());
            }
        }
Mathias af Jochnick Send private email
Thursday, June 04, 2009
 
 
the method being called (getSourceData):

        try {
            connection = getConnection();
            PreparedStatement statement = connection.prepareStatement(sql);
            rs.setResultSet(new ResultSetTemplateModel(statement.executeQuery()));
            rs.setParameterName(parameterName);
        } catch (SQLException e) {
            logger.error("SQLSource;getSourceData;executing SQL", e);
            throw new TransformException(TransformExceptionCause.SOURCE_DATA,"Problem executing SQL: "+e.getMessage());
        }finally {
            try {
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                logger.error("SQLSource;getSourceData;closing connection;" + e.toString());
            }
        }

the getconnection method in the getSourceData object:
private Connection getConnection() throws SQLException{
        connection = dataSource.getConnection();
        connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
        return connection;
    }

I have checked the atomikos trace and it seems to commit properly.

I have debugged and the flow is exactly as expected, with close and commit being called.

Eventually, the calls hang waiting in the getconnection method, and if you look while debugging the datasource connectionpool thinks that all of its connections are taken, running the SQL that originally caused the exception to be thrown, even though close on connection, and commit on atomikos transactions have been called...
Mathias af Jochnick Send private email
Thursday, June 04, 2009
 
 
I couldn't find anything wrong with the above code, but i did find a couple of things i could do to make the datasource NOT keep the connections:

ONE:
The actual connection object was kept in a reference outside of the method (as you see there is no Connection reference created in the method, a global reference is used).

However, if I insert a
"Connection connection = null;"

into both the getsourcedata and getconnection methods, and remove the global reference, the problem goes away...

TWO:
The other thing i could do was to not throw an exception in the "getsourcedata" method, but just eat the exception and return null. In that case, connections are returned ok.

THREE:
The final thing, is to remove the tm.begin and tm.commit, this results in that exceptions can be thrown without connections being kept by the data source. This of course makes me suspect the atomikos transaction manager.


If anyone has anything clever to point out regarding this, i'd be most interested to hear it. :)
Mathias af Jochnick Send private email
Thursday, June 04, 2009
 
 
Hi,

@ONE: if you remove global references then this suggests that close works better, meaning there is a connection leak in your code?

@TWO: same thing

@THREE: if you remove the logs etc. then commit will fail/retry and not release the connection for reuse until it finally gives up - this is normal

I don't think there is a bug here, but we'll check to make sure.

Thanks for the feedback!

Guy
Guy Pardon Send private email
Friday, June 05, 2009
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics