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