You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Bernd Eckenfels <ec...@zusammenkunft.net> on 2015/07/27 22:42:30 UTC

[dbcp] aborting abandoned connections

Hello,

I was investigating the behavior of dbcp in regards to killing
longrunning/hanging statements (specifically for the Oracle driver).

Oracle driver synchronizes on the physical connection for some things
like connection.close() or statement.close() or .isClosed() or
the vendor specific _getPC().

This can cause the abandoned connection close of commons-pool to hang.
There are some (older) driver specific methods to work around this, and
there is also a new JDBC method in Java 7:


http://docs.oracle.com/javase/7/docs/api/java/sql/Connection.html#abort%28java.util.concurrent.Executor%29

If you do not use this method, the hang will look like this:

"commons-pool-EvictionTimer" Id=12 BLOCKED on
oracle.jdbc.driver.T4CConnection@3cd1f1c8 owned by "Thread-2" Id=14
	at
oracle.jdbc.driver.OracleStatement.close(OracleStatement.java:1343)
	-  blocked on oracle.jdbc.driver.T4CConnection@3cd1f1c8
	at
oracle.jdbc.driver.OracleStatementWrapper.close(OracleStatementWrapper.java:100)
	at
oracle.jdbc.driver.OraclePreparedStatementWrapper.close(OraclePreparedStatementWrapper.java:82)
	at
org.apache.commons.dbcp2.DelegatingStatement.close(DelegatingStatement.java:156)
	at
org.apache.commons.dbcp2.DelegatingConnection.passivate(DelegatingConnection.java:631)
	at
org.apache.commons.dbcp2.PoolableConnection.passivate(PoolableConnection.java:127)
	at
org.apache.commons.dbcp2.DelegatingConnection.closeInternal(DelegatingConnection.java:232)
	at
org.apache.commons.dbcp2.PoolableConnection.reallyClose(PoolableConnection.java:243)

I would add an optional policy to close the connection which can do the
old way (close all statements then the connection) or a JDBC 4.1 way
(using abort(exe) only) or even some drive specific way (calling
abort() via relfection).

I wonder if it should be different for killing abandoned and killing
expired connections, but I think since all of them are terminated, all
can use the same strict method for purging them,

Some test code (for Oracle driver) with output is here:

https://gist.github.com/ecki/345ee08ac97820972fe7

Gruss
Bernd


 Am
Mon, 27 Jul 2015 08:47:45 -0700 schrieb Phil Steitz
<ph...@gmail.com>:

> On 7/27/15 7:18 AM, Bernd wrote:
> > Hi Phil,
> >
> > ah great, I can confirm that it is logging something if I add the
> > auto flush:
> >
> > https://gist.github.com/ecki/345ee08ac97820972fe7#file-result-autoflush4s-txt
> >
> > (It even logs the active statements, so I guess it tries to kill
> > them (but get blocked by my initial problem). What do you think
> > does it make sense to provide a JDBC compliant abort() variant?)
> 
> I was thinking about suggesting that on dev@ - would you mind
> posting there?

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [dbcp] aborting abandoned connections

Posted by Phil Steitz <ph...@gmail.com>.
On 7/27/15 1:42 PM, Bernd Eckenfels wrote:
> Hello,
>
> I was investigating the behavior of dbcp in regards to killing
> longrunning/hanging statements (specifically for the Oracle driver).
>
> Oracle driver synchronizes on the physical connection for some things
> like connection.close() or statement.close() or .isClosed() or
> the vendor specific _getPC().
>
> This can cause the abandoned connection close of commons-pool to hang.
> There are some (older) driver specific methods to work around this, and
> there is also a new JDBC method in Java 7:
>
>
> http://docs.oracle.com/javase/7/docs/api/java/sql/Connection.html#abort%28java.util.concurrent.Executor%29
>
> If you do not use this method, the hang will look like this:
>
> "commons-pool-EvictionTimer" Id=12 BLOCKED on
> oracle.jdbc.driver.T4CConnection@3cd1f1c8 owned by "Thread-2" Id=14
> 	at
> oracle.jdbc.driver.OracleStatement.close(OracleStatement.java:1343)
> 	-  blocked on oracle.jdbc.driver.T4CConnection@3cd1f1c8
> 	at
> oracle.jdbc.driver.OracleStatementWrapper.close(OracleStatementWrapper.java:100)
> 	at
> oracle.jdbc.driver.OraclePreparedStatementWrapper.close(OraclePreparedStatementWrapper.java:82)
> 	at
> org.apache.commons.dbcp2.DelegatingStatement.close(DelegatingStatement.java:156)
> 	at
> org.apache.commons.dbcp2.DelegatingConnection.passivate(DelegatingConnection.java:631)
> 	at
> org.apache.commons.dbcp2.PoolableConnection.passivate(PoolableConnection.java:127)
> 	at
> org.apache.commons.dbcp2.DelegatingConnection.closeInternal(DelegatingConnection.java:232)
> 	at
> org.apache.commons.dbcp2.PoolableConnection.reallyClose(PoolableConnection.java:243)
>
> I would add an optional policy to close the connection which can do the
> old way (close all statements then the connection) or a JDBC 4.1 way
> (using abort(exe) only) or even some drive specific way (calling
> abort() via relfection).
>
> I wonder if it should be different for killing abandoned and killing
> expired connections, but I think since all of them are terminated, all
> can use the same strict method for purging them,

+1 - I see no reason to treat abandoned connections differently.
>
> Some test code (for Oracle driver) with output is here:
>
> https://gist.github.com/ecki/345ee08ac97820972fe7

This seems like a reasonable enhancement request to me.  We would
definitely want to make it configurable and off by default because
of the security and driver support requirements.  We would also have
to agree on a way to manage Executors and think carefully through
the consequences of moving to async close operations.  If no one has
objections to pursuing this, I will open a JIRA and we can start
exploring for 2.2.

Phil

>
> Gruss
> Bernd
>
>
>  Am
> Mon, 27 Jul 2015 08:47:45 -0700 schrieb Phil Steitz
> <ph...@gmail.com>:
>
>> On 7/27/15 7:18 AM, Bernd wrote:
>>> Hi Phil,
>>>
>>> ah great, I can confirm that it is logging something if I add the
>>> auto flush:
>>>
>>> https://gist.github.com/ecki/345ee08ac97820972fe7#file-result-autoflush4s-txt
>>>
>>> (It even logs the active statements, so I guess it tries to kill
>>> them (but get blocked by my initial problem). What do you think
>>> does it make sense to provide a JDBC compliant abort() variant?)
>> I was thinking about suggesting that on dev@ - would you mind
>> posting there?



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org