You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ps...@apache.org on 2011/04/24 01:03:00 UTC
svn commit: r1096255 - in
/commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src: changes/
java/org/apache/commons/dbcp/ site/xdoc/ test/org/apache/commons/dbcp/
Author: psteitz
Date: Sat Apr 23 23:03:00 2011
New Revision: 1096255
URL: http://svn.apache.org/viewvc?rev=1096255&view=rev
Log:
Modified execute methods of Statement objects to ensure that whenever
a statement is used, the lastUsed property of its parent connection is updated.
JIRA: DBCP-343
Modified:
commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/changes/changes.xml
commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/AbandonedConfig.java
commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/BasicDataSource.java
commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/DelegatingPreparedStatement.java
commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/DelegatingStatement.java
commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/site/xdoc/configuration.xml
commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/test/org/apache/commons/dbcp/TestAbandonedBasicDataSource.java
commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/test/org/apache/commons/dbcp/TesterPreparedStatement.java
Modified: commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/changes/changes.xml?rev=1096255&r1=1096254&r2=1096255&view=diff
==============================================================================
--- commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/changes/changes.xml (original)
+++ commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/changes/changes.xml Sat Apr 23 23:03:00 2011
@@ -39,6 +39,11 @@ The <action> type attribute can be add,u
</properties>
<body>
<release version="1.4.1" date="TBD" description="TBD">
+ <action dev="psteitz" issue="DBCP-343" type="fix">
+ Modified execute methods of Statement objects to ensure that whenever
+ a statement is used, the lastUsed property of its parent connection is
+ updated.
+ </action>
<action dev="psteitz" issue="DBCP-346" type="update" due-to="Ken Tatsushita">
LIFO configuration option has been added to BasicDataSource. When set
to true (the default), the pool acts as a LIFO queue; setting to false
Modified: commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/AbandonedConfig.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/AbandonedConfig.java?rev=1096255&r1=1096254&r2=1096255&view=diff
==============================================================================
--- commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/AbandonedConfig.java (original)
+++ commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/AbandonedConfig.java Sat Apr 23 23:03:00 2011
@@ -34,14 +34,14 @@ public class AbandonedConfig {
private boolean removeAbandoned = false;
/**
- * Flag to remove abandoned connections if they exceed the
- * removeAbandonedTimeout.
+ * <p>Flag to remove abandoned connections if they exceed the
+ * removeAbandonedTimeout.</p>
*
- * Set to true or false, default false.
- * If set to true a connection is considered abandoned and eligible
- * for removal if it has been idle longer than the removeAbandonedTimeout.
- * Setting this to true can recover db connections from poorly written
- * applications which fail to close a connection.
+ * <p>The default value is false.</p>
+ *
+ * <p>If set to true a connection is considered abandoned and eligible
+ * for removal if it has been idle longer than the
+ * {@link #getRemoveAbandoned() removeAbandonedTimeout}.</p>
*
* @return true if abandoned connections are to be removed
*/
@@ -50,17 +50,16 @@ public class AbandonedConfig {
}
/**
- * Flag to remove abandoned connections if they exceed the
- * removeAbandonedTimeout.
+ * <p>Flag to remove abandoned connections if they exceed the
+ * removeAbandonedTimeout.</p>
*
- * Set to true or false, default false.
- * If set to true a connection is considered abandoned and eligible
- * for removal if it has been idle longer than the removeAbandonedTimeout.
- * Setting this to true can recover db connections from poorly written
- * applications which fail to close a connection.
+ * <p>If set to true a connection is considered abandoned and eligible
+ * for removal if it has been idle longer than the
+ * {@link #getRemoveAbandoned() removeAbandonedTimeout}.</p>
*
* @param removeAbandoned true means abandoned connections will be
* removed
+ * @see #getRemoveAbandoned()
*/
public void setRemoveAbandoned(boolean removeAbandoned) {
this.removeAbandoned = removeAbandoned;
@@ -71,23 +70,36 @@ public class AbandonedConfig {
*/
private int removeAbandonedTimeout = 300;
- /**
- * Timeout in seconds before an abandoned connection can be removed.
- *
- * Defaults to 300 seconds.
- *
- * @return abandoned timeout in seconds
+ /**
+ * <p>Timeout in seconds before an abandoned connection can be removed.</p>
+ *
+ * <p>Creating a Statement, PreparedStatement or CallableStatement or using
+ * one of these to execute a query (using one of the execute methods)
+ * resets the lastUsed property of the parent connection.</p>
+ *
+ * <p>Abandoned connection cleanup happens when
+ * <code><ul>
+ * <li><code>{@link #getRemoveAbandoned() removeAbandoned} == true</li>
+ * <li>{@link #getNumIdle() numIdle < 2</li>
+ * <li>{@link #getNumActive() numActive} > {@link #getMaxActive() maxActive} - 3</li>
+ * </ul></code></p>
+ *
+ * <p>The default value is 300 seconds.</p>
*/
public int getRemoveAbandonedTimeout() {
return (this.removeAbandonedTimeout);
}
/**
- * Timeout in seconds before an abandoned connection can be removed.
- *
- * Defaults to 300 seconds.
+ * <p>Sets the timeout in seconds before an abandoned connection can be
+ * removed.</p>
+ *
+ * <p>Setting this property has no effect if
+ * {@link #getRemoveAbandoned() removeAbandoned} is false.</p>
*
- * @param removeAbandonedTimeout abandoned timeout in seconds
+ * @param removeAbandonedTimeout new abandoned timeout in seconds
+ * @see #getRemoveAbandonedTimeout()
+ * @see #getRemoveAbandoned()
*/
public void setRemoveAbandonedTimeout(int removeAbandonedTimeout) {
this.removeAbandonedTimeout = removeAbandonedTimeout;
Modified: commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/BasicDataSource.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/BasicDataSource.java?rev=1096255&r1=1096254&r2=1096255&view=diff
==============================================================================
--- commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/BasicDataSource.java (original)
+++ commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/BasicDataSource.java Sat Apr 23 23:03:00 2011
@@ -1180,20 +1180,22 @@ public class BasicDataSource implements
private AbandonedConfig abandonedConfig;
/**
- * Flag to remove abandoned connections if they exceed the
- * removeAbandonedTimout.
+ * <p>Flag to remove abandoned connections if they exceed the
+ * removeAbandonedTimout.</p>
*
- * Set to true or false, default false.
- * If set to true a connection is considered abandoned and eligible
- * for removal if it has been idle longer than the removeAbandonedTimeout.
- * Setting this to true can recover db connections from poorly written
- * applications which fail to close a connection.
- * <p>
- * Abandonded connections are identified and removed when
+ * <p>The default value is false.<p>
+ *
+ * <p>If set to true a connection is considered abandoned and eligible
+ * for removal if it has not been used for more than
+ * {@link #getRemoveAbandonedTimeout() removeAbandonedTimeout} seconds.</p>
+ *
+ * <p>Abandoned connections are identified and removed when
* {@link #getConnection()} is invoked and the following conditions hold
* <ul><li>{@link #getRemoveAbandoned()} = true </li>
* <li>{@link #getNumActive()} > {@link #getMaxActive()} - 3 </li>
* <li>{@link #getNumIdle()} < 2 </li></ul></p>
+ *
+ * @see #getRemoveAbandonedTimeout()
*/
public boolean getRemoveAbandoned() {
if (abandonedConfig != null) {
@@ -1203,7 +1205,18 @@ public class BasicDataSource implements
}
/**
- * @param removeAbandoned new removeAbandoned property value
+ * <p>Flag to remove abandoned connections if they exceed the
+ * removeAbandonedTimeout.</p>
+ *
+ * <p>If set to true a connection is considered abandoned and eligible
+ * for removal if it has been idle longer than the
+ * {@link #getRemoveAbandoned() removeAbandonedTimeout}.</p>
+ *
+ * <p>Setting this to true can recover db connections from poorly written
+ * applications which fail to close a connection.</p>
+ *
+ * @param removeAbandoned true means abandoned connections will be
+ * removed
* @see #getRemoveAbandoned()
*/
public void setRemoveAbandoned(boolean removeAbandoned) {
@@ -1214,12 +1227,22 @@ public class BasicDataSource implements
this.restartNeeded = true;
}
- /**
- * Timeout in seconds before an abandoned connection can be removed.
- *
- * Defaults to 300 seconds.
- * @return abandoned connection timeout
- */
+ /**
+ * <p>Timeout in seconds before an abandoned connection can be removed.</p>
+ *
+ * <p>Creating a Statement, PreparedStatement or CallableStatement or using
+ * one of these to execute a query (using one of the execute methods)
+ * resets the lastUsed property of the parent connection.</p>
+ *
+ * <p>Abandoned connection cleanup happens when
+ * <code><ul>
+ * <li><code>{@link #getRemoveAbandoned() removeAbandoned} == true</li>
+ * <li>{@link #getNumIdle() numIdle < 2</li>
+ * <li>{@link #getNumActive() numActive} > {@link #getMaxActive() maxActive} - 3</li>
+ * </ul></code></p>
+ *
+ * <p>The default value is 300 seconds.</p>
+ */
public int getRemoveAbandonedTimeout() {
if (abandonedConfig != null) {
return abandonedConfig.getRemoveAbandonedTimeout();
@@ -1228,7 +1251,15 @@ public class BasicDataSource implements
}
/**
- * @param removeAbandonedTimeout new removeAbandonedTimeout value
+ * <p>Sets the timeout in seconds before an abandoned connection can be
+ * removed.</p>
+ *
+ * <p>Setting this property has no effect if
+ * {@link #getRemoveAbandoned() removeAbandoned} is false.</p>
+ *
+ * @param removeAbandonedTimeout new abandoned timeout in seconds
+ * @see #getRemoveAbandonedTimeout()
+ * @see #getRemoveAbandoned()
*/
public void setRemoveAbandonedTimeout(int removeAbandonedTimeout) {
if (abandonedConfig == null) {
Modified: commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/DelegatingPreparedStatement.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/DelegatingPreparedStatement.java?rev=1096255&r1=1096254&r2=1096255&view=diff
==============================================================================
--- commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/DelegatingPreparedStatement.java (original)
+++ commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/DelegatingPreparedStatement.java Sat Apr 23 23:03:00 2011
@@ -92,6 +92,9 @@ public class DelegatingPreparedStatement
public ResultSet executeQuery() throws SQLException {
checkOpen();
+ if (_conn != null) {
+ _conn.setLastUsed();
+ }
try {
return DelegatingResultSet.wrapResultSet(this,((PreparedStatement)_stmt).executeQuery());
}
@@ -101,8 +104,18 @@ public class DelegatingPreparedStatement
}
}
- public int executeUpdate() throws SQLException
- { checkOpen(); try { return ((PreparedStatement)_stmt).executeUpdate(); } catch (SQLException e) { handleException(e); return 0; } }
+ public int executeUpdate() throws SQLException {
+ checkOpen();
+ if (_conn != null) {
+ _conn.setLastUsed();
+ }
+ try {
+ return ((PreparedStatement) _stmt).executeUpdate();
+ } catch (SQLException e) {
+ handleException(e);
+ return 0;
+ }
+ }
public void setNull(int parameterIndex, int sqlType) throws SQLException
{ checkOpen(); try { ((PreparedStatement)_stmt).setNull(parameterIndex,sqlType); } catch (SQLException e) { handleException(e); } }
@@ -168,8 +181,18 @@ public class DelegatingPreparedStatement
public void setObject(int parameterIndex, Object x) throws SQLException
{ checkOpen(); try { ((PreparedStatement)_stmt).setObject(parameterIndex, x); } catch (SQLException e) { handleException(e); } }
- public boolean execute() throws SQLException
- { checkOpen(); try { return ((PreparedStatement)_stmt).execute(); } catch (SQLException e) { handleException(e); return false; } }
+ public boolean execute() throws SQLException {
+ checkOpen();
+ if (_conn != null) {
+ _conn.setLastUsed();
+ }
+ try {
+ return ((PreparedStatement) _stmt).execute();
+ } catch (SQLException e) {
+ handleException(e);
+ return false;
+ }
+ }
public void addBatch() throws SQLException
{ checkOpen(); try { ((PreparedStatement)_stmt).addBatch(); } catch (SQLException e) { handleException(e); } }
Modified: commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/DelegatingStatement.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/DelegatingStatement.java?rev=1096255&r1=1096254&r2=1096255&view=diff
==============================================================================
--- commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/DelegatingStatement.java (original)
+++ commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/java/org/apache/commons/dbcp/DelegatingStatement.java Sat Apr 23 23:03:00 2011
@@ -204,6 +204,9 @@ public class DelegatingStatement extends
public ResultSet executeQuery(String sql) throws SQLException {
checkOpen();
+ if (_conn != null) {
+ _conn.setLastUsed();
+ }
try {
return DelegatingResultSet.wrapResultSet(this,_stmt.executeQuery(sql));
}
@@ -224,8 +227,17 @@ public class DelegatingStatement extends
}
}
- public int executeUpdate(String sql) throws SQLException
- { checkOpen(); try { return _stmt.executeUpdate(sql); } catch (SQLException e) { handleException(e); return 0; } }
+ public int executeUpdate(String sql) throws SQLException {
+ checkOpen();
+ if (_conn != null) {
+ _conn.setLastUsed();
+ }
+ try {
+ return _stmt.executeUpdate(sql);
+ } catch (SQLException e) {
+ handleException(e); return 0;
+ }
+ }
public int getMaxFieldSize() throws SQLException
{ checkOpen(); try { return _stmt.getMaxFieldSize(); } catch (SQLException e) { handleException(e); return 0; } }
@@ -260,8 +272,18 @@ public class DelegatingStatement extends
public void setCursorName(String name) throws SQLException
{ checkOpen(); try { _stmt.setCursorName(name); } catch (SQLException e) { handleException(e); } }
- public boolean execute(String sql) throws SQLException
- { checkOpen(); try { return _stmt.execute(sql); } catch (SQLException e) { handleException(e); return false; } }
+ public boolean execute(String sql) throws SQLException {
+ checkOpen();
+ if (_conn != null) {
+ _conn.setLastUsed();
+ }
+ try {
+ return _stmt.execute(sql);
+ } catch (SQLException e) {
+ handleException(e);
+ return false;
+ }
+ }
public int getUpdateCount() throws SQLException
{ checkOpen(); try { return _stmt.getUpdateCount(); } catch (SQLException e) { handleException(e); return 0; } }
@@ -293,8 +315,18 @@ public class DelegatingStatement extends
public void clearBatch() throws SQLException
{ checkOpen(); try { _stmt.clearBatch(); } catch (SQLException e) { handleException(e); } }
- public int[] executeBatch() throws SQLException
- { checkOpen(); try { return _stmt.executeBatch(); } catch (SQLException e) { handleException(e); throw new AssertionError(); } }
+ public int[] executeBatch() throws SQLException {
+ checkOpen();
+ if (_conn != null) {
+ _conn.setLastUsed();
+ }
+ try {
+ return _stmt.executeBatch();
+ } catch (SQLException e) {
+ handleException(e);
+ throw new AssertionError();
+ }
+ }
/**
* Returns a String representation of this object.
@@ -319,23 +351,83 @@ public class DelegatingStatement extends
}
}
- public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException
- { checkOpen(); try { return _stmt.executeUpdate(sql, autoGeneratedKeys); } catch (SQLException e) { handleException(e); return 0; } }
+ public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+ checkOpen();
+ if (_conn != null) {
+ _conn.setLastUsed();
+ }
+ try {
+ return _stmt.executeUpdate(sql, autoGeneratedKeys);
+ } catch (SQLException e) {
+ handleException(e);
+ return 0;
+ }
+ }
- public int executeUpdate(String sql, int columnIndexes[]) throws SQLException
- { checkOpen(); try { return _stmt.executeUpdate(sql, columnIndexes); } catch (SQLException e) { handleException(e); return 0; } }
+ public int executeUpdate(String sql, int columnIndexes[]) throws SQLException {
+ checkOpen();
+ if (_conn != null) {
+ _conn.setLastUsed();
+ }
+ try {
+ return _stmt.executeUpdate(sql, columnIndexes);
+ } catch (SQLException e) {
+ handleException(e);
+ return 0;
+ }
+ }
- public int executeUpdate(String sql, String columnNames[]) throws SQLException
- { checkOpen(); try { return _stmt.executeUpdate(sql, columnNames); } catch (SQLException e) { handleException(e); return 0; } }
+ public int executeUpdate(String sql, String columnNames[]) throws SQLException {
+ checkOpen();
+ if (_conn != null) {
+ _conn.setLastUsed();
+ }
+ try {
+ return _stmt.executeUpdate(sql, columnNames);
+ } catch (SQLException e) {
+ handleException(e);
+ return 0;
+ }
+ }
- public boolean execute(String sql, int autoGeneratedKeys) throws SQLException
- { checkOpen(); try { return _stmt.execute(sql, autoGeneratedKeys); } catch (SQLException e) { handleException(e); return false; } }
+ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+ checkOpen();
+ if (_conn != null) {
+ _conn.setLastUsed();
+ }
+ try {
+ return _stmt.execute(sql, autoGeneratedKeys);
+ } catch (SQLException e) {
+ handleException(e);
+ return false;
+ }
+ }
- public boolean execute(String sql, int columnIndexes[]) throws SQLException
- { checkOpen(); try { return _stmt.execute(sql, columnIndexes); } catch (SQLException e) { handleException(e); return false; } }
+ public boolean execute(String sql, int columnIndexes[]) throws SQLException {
+ checkOpen();
+ if (_conn != null) {
+ _conn.setLastUsed();
+ }
+ try {
+ return _stmt.execute(sql, columnIndexes);
+ } catch (SQLException e) {
+ handleException(e);
+ return false;
+ }
+ }
- public boolean execute(String sql, String columnNames[]) throws SQLException
- { checkOpen(); try { return _stmt.execute(sql, columnNames); } catch (SQLException e) { handleException(e); return false; } }
+ public boolean execute(String sql, String columnNames[]) throws SQLException {
+ checkOpen();
+ if (_conn != null) {
+ _conn.setLastUsed();
+ }
+ try {
+ return _stmt.execute(sql, columnNames);
+ } catch (SQLException e) {
+ handleException(e);
+ return false;
+ }
+ }
public int getResultSetHoldability() throws SQLException
{ checkOpen(); try { return _stmt.getResultSetHoldability(); } catch (SQLException e) { handleException(e); return 0; } }
Modified: commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/site/xdoc/configuration.xml
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/site/xdoc/configuration.xml?rev=1096255&r1=1096254&r2=1096255&view=diff
==============================================================================
--- commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/site/xdoc/configuration.xml (original)
+++ commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/site/xdoc/configuration.xml Sat Apr 23 23:03:00 2011
@@ -338,7 +338,10 @@ Be carefull and only use when you need d
Flag to remove abandoned connections if they exceed the
removeAbandonedTimout.<br/>
If set to true a connection is considered abandoned and eligible
- for removal if it has been idle longer than the removeAbandonedTimeout.
+ for removal if it has not been used for longer than the removeAbandonedTimeout.<br/>
+ Creating a Statement, PreparedStatement or CallableStatement or using
+ one of these to execute a query (using one of the execute methods)
+ resets the lastUsed property of the parent connection.<br/>
Setting this to true can recover db connections from poorly written
applications which fail to close a connection.
</td>
@@ -362,14 +365,17 @@ Be carefull and only use when you need d
</table>
<p>
<img src="images/icon_info_sml.gif"/>
-If you have enabled "removeAbandoned" then it is possible that a connection is reclaimed by the pool because it is considered to be abandoned.
-This mechanism is triggered when (getNumIdle() < 2) and (getNumActive() > getMaxActive() - 3)
+If you have enabled "removeAbandoned" then it is possible that a connection is reclaimed by the pool because
+it is considered to be abandoned. This mechanism is triggered when (getNumIdle() < 2) and
+(getNumActive() > getMaxActive() - 3)
</p>
<p>
<img src="images/icon_info_sml.gif"/>
-For example maxActive=20 and 18 active connections and 1 idle connection would trigger the "removeAbandoned".
+For example, maxActive=20 and 18 active connections and 1 idle connection would trigger the "removeAbandoned".
But only the active connections that aren't used for more then "removeAbandonedTimeout" seconds are removed,
-default (300 sec). Traversing a resultset doesn't count as being used.
+default (300 sec). Traversing a resultset doesn't count as being used. Creating a Statement, PreparedStatement
+or CallableStatement or using one of these to execute a query (using one of the execute methods) resets
+the lastUsed property of the parent connection.
</p>
</section>
Modified: commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/test/org/apache/commons/dbcp/TestAbandonedBasicDataSource.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/test/org/apache/commons/dbcp/TestAbandonedBasicDataSource.java?rev=1096255&r1=1096254&r2=1096255&view=diff
==============================================================================
--- commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/test/org/apache/commons/dbcp/TestAbandonedBasicDataSource.java (original)
+++ commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/test/org/apache/commons/dbcp/TestAbandonedBasicDataSource.java Sat Apr 23 23:03:00 2011
@@ -19,7 +19,10 @@ package org.apache.commons.dbcp;
import java.io.IOException;
import java.sql.Connection;
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
import java.sql.SQLException;
+import java.sql.Statement;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -160,4 +163,87 @@ public class TestAbandonedBasicDataSourc
ds.getConnection(); // trigger abandoned cleanup again
conn1.createStatement();
}
+
+ /**
+ * DBCP-343 - verify that using a DelegatingStatement updates
+ * the lastUsed on the parent connection
+ */
+ public void testLastUsedPreparedStatementUse() throws Exception {
+ ds.setRemoveAbandonedTimeout(1);
+ ds.setMaxActive(2);
+ Connection conn1 = ds.getConnection();
+ Statement st = conn1.createStatement();
+ String querySQL = "SELECT 1 FROM DUAL";
+ Thread.sleep(500);
+ st.executeQuery(querySQL); // Should reset lastUsed
+ Thread.sleep(800);
+ Connection conn2 = ds.getConnection(); // triggers abandoned cleanup
+ st.executeQuery(querySQL); // Should still be OK
+ conn2.close();
+ Thread.sleep(500);
+ st.executeUpdate(""); // Should also reset
+ Thread.sleep(800);
+ ds.getConnection(); // trigger abandoned cleanup again
+ conn1.createStatement(); // Connection should still be good
+ }
+
+ /**
+ * DBCP-343 - verify additional operations reset lastUsed on
+ * the parent connection
+ */
+ public void testLastUsedUpdate() throws Exception {
+ DelegatingConnection conn = (DelegatingConnection) ds.getConnection();
+ PreparedStatement ps = conn.prepareStatement("");
+ CallableStatement cs = conn.prepareCall("");
+ Statement st = conn.prepareStatement("");
+ checkLastUsedStatement(ps, conn);
+ checkLastUsedPreparedStatement(ps, conn);
+ checkLastUsedStatement(cs, conn);
+ checkLastUsedPreparedStatement(cs, conn);
+ checkLastUsedStatement(st, conn);
+ }
+
+ /**
+ * Verifies that Statement executeXxx methods update lastUsed on the parent connection
+ */
+ private void checkLastUsedStatement(Statement st, DelegatingConnection conn) throws Exception {
+ st.execute("");
+ assertAndReset(conn);
+ st.execute("", new int[] {});
+ assertAndReset(conn);
+ st.execute("", 0);
+ assertAndReset(conn);
+ st.executeBatch();
+ assertAndReset(conn);
+ st.executeQuery("");
+ assertAndReset(conn);
+ st.executeUpdate("");
+ assertAndReset(conn);
+ st.executeUpdate("", new int[] {});
+ assertAndReset(conn);
+ st.executeUpdate("", 0);
+ assertAndReset(conn);
+ st.executeUpdate("", new String[] {});
+ assertAndReset(conn);
+ }
+
+ /**
+ * Verifies that PreparedStatement executeXxx methods update lastUsed on the parent connection
+ */
+ private void checkLastUsedPreparedStatement(PreparedStatement ps, DelegatingConnection conn) throws Exception {
+ ps.execute();
+ assertAndReset(conn);
+ ps.executeQuery();
+ assertAndReset(conn);
+ ps.executeUpdate();
+ assertAndReset(conn);
+ }
+
+ /**
+ * Verifies that con.lastUsed has been updated and then resets it to 0
+ */
+ private void assertAndReset(DelegatingConnection con) {
+ assertTrue(con.getLastUsed() > 0);
+ con.setLastUsed(0);
+ }
}
Modified: commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/test/org/apache/commons/dbcp/TesterPreparedStatement.java
URL: http://svn.apache.org/viewvc/commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/test/org/apache/commons/dbcp/TesterPreparedStatement.java?rev=1096255&r1=1096254&r2=1096255&view=diff
==============================================================================
--- commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/test/org/apache/commons/dbcp/TesterPreparedStatement.java (original)
+++ commons/proper/dbcp/branches/DBCP_1_4_x_BRANCH/src/test/org/apache/commons/dbcp/TesterPreparedStatement.java Sat Apr 23 23:03:00 2011
@@ -249,32 +249,32 @@ public class TesterPreparedStatement ext
public int executeUpdate(String sql, int autoGeneratedKeys)
throws SQLException {
- throw new SQLException("Not implemented.");
+ checkOpen(); return 0;
}
public int executeUpdate(String sql, int columnIndexes[])
throws SQLException {
- throw new SQLException("Not implemented.");
+ checkOpen(); return 0;
}
public int executeUpdate(String sql, String columnNames[])
throws SQLException {
- throw new SQLException("Not implemented.");
+ checkOpen(); return 0;
}
public boolean execute(String sql, int autoGeneratedKeys)
throws SQLException {
- throw new SQLException("Not implemented.");
+ checkOpen(); return true;
}
public boolean execute(String sl, int columnIndexes[])
throws SQLException {
- throw new SQLException("Not implemented.");
+ checkOpen(); return true;
}
public boolean execute(String sql, String columnNames[])
throws SQLException {
- throw new SQLException("Not implemented.");
+ checkOpen(); return true;
}
public int getResultSetHoldability() throws SQLException {