问题
I fixed some bug related to the way we were using BasicDataSource and though I understand part of it I still have some questions unanswered :)
Problem: The application was not able to auto-connect to the database after a db failure.
Application is using org.apache.commons.dbcp.BasicDataSource class as a TCP-connection pool for a JDBC connection to Oracle db.
Fix: After some research I discovered that in BasicDataSource testOnBorrow and testOnreturn were not set. I provided the validation query to test connections. This fixed the problem
Max no of connections in pool was set to 1
My Understanding: The connection pool would hand over a connection to the application. What I think was happening was the application MAGICALLY returned the bad collection to the pool when it db crashed . Now since the Pool does not know if it is a bad connection it would hand over the same connection to the application next time it needs it causing the application to not auto-reconnect to db.
Now, after the fix.. whenever a bad connection is returned to the connection pool it would be discarded and wont be used again because of the fix I made above.
Now I know that BasicDataSource wraps the connection before giving to the application, such that whenever application says con.close ..BasicDataSource would know that the connection is not used any more.. it will take care of either returning the connection to the pool or discardigg etc.
Unanswered Question: However what I do not understand is what makes the application MAGICALLY return the connection to the connection pool when its broken[Note that con.close method is not called when the connection exits un-gracefully]. There is no way of BasicDataSource to know that the connection closed or there is ?. Can someone point me to code for that ?
I my overall understanding connect of why the fix worked ??
回答1:
Now, I know that this is kind of an old thread, but it's high on google search results, so I thought I might give it a quick answer. For more information on configuring the BasicDataSource, you should reference the DBCP Configuration page: http://commons.apache.org/proper/commons-dbcp/configuration.html
To answer the "unanaswered" question of "How does BasicDataSource know when a connection is abondoned and needs to be returned to the connection pool?" (paraphrased)...
org.apache.commons.dbcp.BasicDataSource is able to monitor traffic and usage on the connections it offers by using a wrapper class for the Connection. Every time you call a method on the connection or any Statements created from the connection, you are actually calling a wrapper class that implements an interface or extends a base class with those same methods (Hurray for Polymorphism!). These custom methods allow the DataSource to know whether or not a Connection is active.
On the BasicDataSource itself, there is a property called "removeAbandoned" and another called "removeAbandonedTimeout" that are used to configure this behavior of returning abondonded connections to the connection pool.
"removeAbandoned" is a boolean that indicates whether abandoned connections should be returned to the pool. Defaults to "false".
"removeAbandonedTimeout" is an int, that represents the number of seconds of inactivity that should be allowed to pass before a connection is considered to be abandoned. Default value is 300 (about 5 minutes).
回答2:
Looking at the test for abandoned connections, it appears that when all connections in the pool are "in use" when a new connection is requested, the "in-use" connections are tested for abandonment (they maintain a timestamp of last used time).
See BasicDataSource#setRemoveAbandoned(boolean) and BasicDataSource#setRemoveAbandonedTimeout(int)
Regardless of how clever or not your connection pool is in closing abandoned connections, you should always ensure each connection is closed in a finally block, e.g.:
Connection conn = getConnection();
try {
... // perform work
} finally {
conn.close();
}
Or use some other means such as Apache DBUtils.
来源:https://stackoverflow.com/questions/4110883/question-regarding-org-apache-commons-dbcp-basicdatasource