On 11/21/17 11:34 AM, Shawn Heisey wrote:
> On 11/16/2017 5:21 PM, Phil Steitz wrote:
>> That should not be possible, as once a connection has been checked
>> out, it is not eligible for eviction.  And even if it were evicted
>> by the pool, the pool would set the DelegatingConnection's closed
>> property to true so isValid would return false rather than
>> throwing.  It looks like the situation here is that the pool thinks
>> the connection is open, but the underlying physical connection has
>> been closed.
> I am very glad to hear you describe the intended operation this way --
> the gist of which seems to say that when getConnection is called, it
> *should* immediately mark that connection as ineligible for eviction.
>
> My current suspicion is that there is a bug, where getConnection isn't
> marking the connection as ineligible like it should, or maybe where
> there is insufficient synchronization to prevent the eviction thread
> from closing/evicting the connection before getConnection *does* mark
> the connection as ineligible.  This is just a theory, but it does fit
> what I've seen.  I have tried to investigate the code, but the project
> has used object inheritance and abstraction very effectively, which
> makes it difficult for me to follow exactly what the code is doing,
> because I am not familiar with all of that inheritance.

It's always possible that there is a bug. The relevant code is in
commons pool.  The code to look at is in
o.a.c.pool2.impl.GenericObjectPool#evict.  The guard is here:

if (!underTest.startEvictionTest()) {
    // Object was borrowed in another thread
    // Don't count this as an eviction test so reduce i;
    i--;
    continue;
 }

The objects that the pool works with are PooledObjects.  DBCP's
PoolableConnectionFactory creates DefaultPooledObjects, which
implement the method above by returning false unless the object is
idle in the pool.  If it is idle in the pool, its state is changed
to indicate that it is under test.  This method is synchronized (on
the PooledObject's monitor), as are the other methods that read or
mutate its PooledObjectState.

Before returning an object from the pool to a client,
GenericObjectPool's borrowObject calls the PooledObject's allocate
method.  That method, again synchronized on the object, checks to
make sure that the object's state is idle in the pool.  If so, it
changes its state to allocated and before returning it to the client.

As I said above, it's always possible that there is a bug somewhere,
but the setup is simple and it has been hammered pretty hard for a
few years now.
>
> I am not aware of any way for one thread in my code to close a
> connection obtained by another thread.  My design intent is to ensure
> that this is completely impossible, by handling the full lifecycle of a
> connection in one thread and never passing connections between threads. 
> I am not aware of any places in the program that violate this design
> intent ... but I've written plenty of bugs in my time, so it's always
> possible that I *have* made a mistake like that.

As I said in my first response, the most common explanation for this
kind of exception when using DBCP is that the underlying physical
connection is closed on the server (or network) side without DBCP
knowing about it.  And the most common cause of that is server-side
idle connection timeout.

It just occurred to me that since you do not have any of the testXxx
flags set to true, DBCP is never actually exercising the
connections.  Is it possible that sometimes your code checks out a
connection from the pool but does not use it?  "Idle" to DBCP/Pool
means idle in the pool - i.e., not checked out to a client.  So if
connections are checked out and checked back in without being used,
they will not be evicted, but could be timed out by the server.

Phil
>
> Thanks,
> Shawn
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscr...@commons.apache.org
> For additional commands, e-mail: user-h...@commons.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscr...@commons.apache.org
For additional commands, e-mail: user-h...@commons.apache.org

Reply via email to