From a16b0a8412928606d4f34ce415c094e38b4a0f57 Mon Sep 17 00:00:00 2001 From: wenshao Date: Mon, 6 Aug 2012 17:42:09 +0800 Subject: [PATCH] bug fixed for StatFilter resultSet multi-close --- .../alibaba/druid/filter/stat/StatFilter.java | 7 +- .../druid/proxy/jdbc/ResultSetProxy.java | 2 + .../druid/proxy/jdbc/ResultSetProxyImpl.java | 7 ++ .../StatFilterResultSetMultiCloseTest.java | 64 +++++++++++++++++++ 4 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/StatFilterResultSetMultiCloseTest.java diff --git a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java index a90d94e82c..5985571ed8 100644 --- a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java +++ b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java @@ -63,6 +63,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { public final static String ATTR_UPDATE_COUNT = "stat.updteCount"; public final static String ATTR_TRANSACTION = "stat.tx"; + public final static String ATTR_RESULTSET_CLOSED = "stat.rs.closed"; protected JdbcDataSourceStat dataSourceStat; @@ -551,7 +552,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { String sql = resultSet.getSql(); if (sql != null) { JdbcSqlStat sqlStat = resultSet.getSqlStat(); - if (sqlStat != null) { + if (sqlStat != null && resultSet.getCloseCount() == 0) { sqlStat.addFetchRowCount(fetchCount); long stmtExecuteNano = resultSet.getStatementProxy().getLastExecuteTimeNano(); sqlStat.addResultSetHoldTimeNano(stmtExecuteNano, nanoSpan); @@ -772,7 +773,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { chain.dataSource_recycle(conn); long nanos = System.nanoTime() - conn.getConnectedTimeNano(); - + long millis = nanos / (1000L * 1000L); dataSourceStat.getConnectionHoldHistogram().record(millis); } @@ -784,7 +785,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { if (conn != null) { conn.setConnectedTimeNano(System.nanoTime()); } - + return conn; } diff --git a/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxy.java b/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxy.java index a2096f2028..f6a6ff7ef2 100644 --- a/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxy.java +++ b/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxy.java @@ -41,4 +41,6 @@ public interface ResultSetProxy extends ResultSet, WrapperProxy { void setConstructNano(long constructNano); void setConstructNano(); + + int getCloseCount(); } diff --git a/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxyImpl.java b/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxyImpl.java index 39411e481c..45017f8596 100644 --- a/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxyImpl.java +++ b/src/main/java/com/alibaba/druid/proxy/jdbc/ResultSetProxyImpl.java @@ -55,6 +55,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro protected int fetchRowCount = 0; protected long constructNano; protected final JdbcSqlStat sqlStat; + private int closeCount = 0; public ResultSetProxyImpl(StatementProxy statement, ResultSet resultSet, long id, String sql){ super(resultSet, id); @@ -134,6 +135,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro @Override public void close() throws SQLException { createChain().resultSet_close(this); + closeCount++; } @Override @@ -1071,4 +1073,9 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro return super.unwrap(iface); } + + public int getCloseCount() { + return closeCount; + } + } diff --git a/src/test/java/com/alibaba/druid/bvt/filter/StatFilterResultSetMultiCloseTest.java b/src/test/java/com/alibaba/druid/bvt/filter/StatFilterResultSetMultiCloseTest.java new file mode 100644 index 0000000000..76b164a532 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/StatFilterResultSetMultiCloseTest.java @@ -0,0 +1,64 @@ +package com.alibaba.druid.bvt.filter; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.stat.JdbcSqlStat; +import com.alibaba.druid.util.Histogram; +import com.alibaba.druid.util.JdbcUtils; + +public class StatFilterResultSetMultiCloseTest extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setFilters("stat"); + + dataSource.init(); + } + + protected void tearDown() throws Exception { + JdbcUtils.close(dataSource); + } + + public void test_stat() throws Exception { + + final String sql = "SELECT 1"; + Assert.assertTrue(dataSource.isInited()); + + JdbcSqlStat sqlStat = dataSource.getDataSourceStat().getSqlStat(sql); + + Assert.assertNull(sqlStat); + + Connection conn = dataSource.getConnection(); + + PreparedStatement stmt = conn.prepareStatement(sql); + ResultSet rs = stmt.executeQuery(); + rs.next(); + rs.close(); + + sqlStat = dataSource.getDataSourceStat().getSqlStat(sql); + Assert.assertNotNull(sqlStat); + + Histogram histogram = sqlStat.getExecuteAndResultHoldTimeHistogram(); + Assert.assertEquals("first failed", 1, histogram.getValue(0) + histogram.getValue(1)); + + rs.close(); + + Assert.assertEquals("second failed", 1, histogram.getValue(0) + histogram.getValue(1)); + + stmt.close(); + + conn.close(); + + Assert.assertEquals(1, histogram.getValue(1)); + } +}