From 714003911f00d63be0d2ab23a6028005150f9840 Mon Sep 17 00:00:00 2001 From: Jesse Morgan Date: Thu, 5 Mar 2015 15:09:26 -0800 Subject: Fixing leaked JDBC Connections. Fixing a leak if aborting a transaction throws an exception (e.g. request made on closed connection). --- .../carbonado/repo/jdbc/JDBCTransaction.java | 15 +++++++---- .../repo/jdbc/JDBCTransactionManager.java | 30 +++++++++++++++------- 2 files changed, 31 insertions(+), 14 deletions(-) (limited to 'src/main/java/com/amazon/carbonado') diff --git a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCTransaction.java b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCTransaction.java index ffa2e5c..00e6947 100644 --- a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCTransaction.java +++ b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCTransaction.java @@ -106,10 +106,17 @@ class JDBCTransaction { } /** - * @return connection to close, or null if not ready to because this was a - * nested transaction + * @return true if the connection should be closed after the transaction is aborted. */ - Connection abort() throws SQLException { + boolean shouldCloseConnection() { + return !mIsNested; + } + + /** + * Note: The caller should close the connection after aborting if + * shouldCloseConnection() returns true. + */ + void abort() throws SQLException { if (mRegisteredLobs != null) { for (JDBCLob lob : mRegisteredLobs) { lob.close(); @@ -134,13 +141,11 @@ class JDBCTransaction { } } - return null; } else { if (mReady) { mConnection.rollback(); mReady = false; } - return mConnection; } } diff --git a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCTransactionManager.java b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCTransactionManager.java index c649058..9fe2ff4 100644 --- a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCTransactionManager.java +++ b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCTransactionManager.java @@ -97,18 +97,30 @@ class JDBCTransactionManager extends TransactionManager { @Override protected void abortTxn(JDBCTransaction txn) throws PersistException { + PersistException ex = null; + try { - Connection con; - if ((con = txn.abort()) != null) { - JDBCRepository repo = mRepositoryRef.get(); - if (repo == null) { - con.close(); - } else { - repo.closeConnection(con); + txn.abort(); + } catch (Throwable e) { + ex = mExTransformer.toPersistException(e); + throw ex; + } finally { + try { + if (txn.shouldCloseConnection()) { + Connection con = txn.getConnection(); + JDBCRepository repo = mRepositoryRef.get(); + if (repo == null) { + con.close(); + } else { + repo.closeConnection(con); + } + } + } catch (Throwable e) { + // Don't lose the original exception. + if (ex == null) { + throw mExTransformer.toPersistException(e); } } - } catch (Throwable e) { - throw mExTransformer.toPersistException(e); } } } -- cgit v1.2.3