Uploaded image for project: 'Commons DBCP'
  1. Commons DBCP
  2. DBCP-484

Connection leak during XATransaction in high load

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 2.2.0
    • Fix Version/s: 2.4.0
    • Labels:
      None

      Description

      We're experiencing a connection leak in a distributed transaction when the system is under heavy load. We're using commons-dbcp (latest version) + eclipselink and narayana to perform transaction coordination.

      From time to time we can see a stacktrace reporting an abandoned connection. We are trying to figure out what's the root cause and we think that might be some issue in the commons dbcp (not sure) . More specifically, this parte of the code:

      ManagedConnection#updateTransactionStatus

      if (transactionContext != null) {
          if (transactionContext.isActive()) {
              if (transactionContext != transactionRegistry.getActiveTransactionContext()) {
                  throw new SQLException("Connection can not be used while enlisted in another transaction");
              }
              return;
          }
          // transaction should have been cleared up by TransactionContextListener, but in
          // rare cases another lister could have registered which uses the connection before
          // our listener is called.  In that rare case, trigger the transaction complete call now
          transactionComplete();    
      }

       

      If the transactionContext is different than null but the state is not "active" (ex: STATUS_ROLLEDBACK, STATUS_ROLLING_BACK, etc) it executes the transactionComplete mothod that clears the reference to a shared connection and after that the connection is never closed (returned to the pool). 

       

      If we move the transactionComplete(); to an else,(see below), the connection leak does not happen.

      if (transactionContext != null) {
          if (transactionContext.isActive()) {
              if (transactionContext != transactionRegistry.getActiveTransactionContext()) {
                  throw new SQLException("Connection can not be used while enlisted in another transaction");
              }
              return;
          }
      } else {
          transactionComplete();
      }

       

      After this the dbcp unit tests still pass but I'm not sure about this changes. Can you please check?

      Thanks

       

        Attachments

        1. dbcp-test.zip
          13 kB
          Gary D. Gregory

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                ejsfreitas Emanuel Freitas
              • Votes:
                0 Vote for this issue
                Watchers:
                9 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: