diff --git a/src/main/java/com/alibaba/druid/mock/MockConnection.java b/src/main/java/com/alibaba/druid/mock/MockConnection.java index f0d4a38408..cfc6e268e3 100644 --- a/src/main/java/com/alibaba/druid/mock/MockConnection.java +++ b/src/main/java/com/alibaba/druid/mock/MockConnection.java @@ -53,6 +53,8 @@ public class MockConnection extends ConnectionBase implements Connection { private final long createdTimeMillis = System.currentTimeMillis(); private long lastActiveTimeMillis = System.currentTimeMillis(); + private SQLException error; + public MockConnection(){ this(null, null, null); } @@ -67,6 +69,14 @@ public class MockConnection extends ConnectionBase implements Connection { } } + public SQLException getError() { + return error; + } + + public void setError(SQLException error) { + this.error = error; + } + public List getSavepoints() { return savepoints; } @@ -112,9 +122,7 @@ public class MockConnection extends ConnectionBase implements Connection { @Override public Statement createStatement() throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); return createMockStatement(); } @@ -128,53 +136,40 @@ public class MockConnection extends ConnectionBase implements Connection { @Override public PreparedStatement prepareStatement(String sql) throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); return createMockPreparedStatement(sql); } @Override public CallableStatement prepareCall(String sql) throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); return createMockCallableStatement(sql); } @Override public String nativeSQL(String sql) throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); return sql; } @Override public void setAutoCommit(boolean autoCommit) throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); super.setAutoCommit(autoCommit); } @Override public void commit() throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } - + checkState(); } @Override public void rollback() throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); this.savepoints.clear(); } @@ -201,9 +196,7 @@ public class MockConnection extends ConnectionBase implements Connection { @Override public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); MockStatement stmt = createMockStatement(); @@ -216,9 +209,7 @@ public class MockConnection extends ConnectionBase implements Connection { @Override public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); MockPreparedStatement stmt = createMockPreparedStatement(sql); @@ -230,9 +221,7 @@ public class MockConnection extends ConnectionBase implements Connection { @Override public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); MockCallableStatement stmt = createMockCallableStatement(sql); @@ -254,9 +243,7 @@ public class MockConnection extends ConnectionBase implements Connection { @Override public Savepoint setSavepoint() throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); MockSavepoint savepoint = new MockSavepoint(); savepoint.setSavepointId(this.savepointIdSeed++); @@ -267,9 +254,7 @@ public class MockConnection extends ConnectionBase implements Connection { @Override public Savepoint setSavepoint(String name) throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); MockSavepoint savepoint = new MockSavepoint(); savepoint.setSavepointId(this.savepointIdSeed++); @@ -279,12 +264,19 @@ public class MockConnection extends ConnectionBase implements Connection { return savepoint; } - @Override - public void rollback(Savepoint savepoint) throws SQLException { + public void checkState() throws SQLException { + if (error != null) { + throw error; + } + if (closed) { throw new MockConnectionClosedException(); } + } + @Override + public void rollback(Savepoint savepoint) throws SQLException { + checkState(); int index = this.savepoints.indexOf(savepoint); if (index == -1) { @@ -297,9 +289,7 @@ public class MockConnection extends ConnectionBase implements Connection { @Override public void releaseSavepoint(Savepoint savepoint) throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); if (savepoint == null) { throw new SQLException("argument is null"); @@ -315,9 +305,7 @@ public class MockConnection extends ConnectionBase implements Connection { @Override public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); MockStatement stmt = createMockStatement(); @@ -331,9 +319,7 @@ public class MockConnection extends ConnectionBase implements Connection { @Override public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); MockPreparedStatement stmt = createMockPreparedStatement(sql); @@ -354,9 +340,7 @@ public class MockConnection extends ConnectionBase implements Connection { @Override public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); MockCallableStatement stmt = createMockCallableStatement(sql); @@ -376,27 +360,21 @@ public class MockConnection extends ConnectionBase implements Connection { @Override public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); return createMockPreparedStatement(sql); } @Override public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); return createMockPreparedStatement(sql); } @Override public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { - if (closed) { - throw new MockConnectionClosedException(); - } + checkState(); return createMockPreparedStatement(sql); } diff --git a/src/main/java/com/alibaba/druid/pool/DruidConnectionHolder.java b/src/main/java/com/alibaba/druid/pool/DruidConnectionHolder.java index ca8ee6f142..95e8b65fae 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidConnectionHolder.java +++ b/src/main/java/com/alibaba/druid/pool/DruidConnectionHolder.java @@ -30,14 +30,14 @@ import com.alibaba.druid.support.logging.Log; import com.alibaba.druid.support.logging.LogFactory; import com.alibaba.druid.util.IOUtils; import com.alibaba.druid.util.JdbcConstants; -import com.alibaba.druid.util.JdbcUtils; /** * @author wenshao */ public final class DruidConnectionHolder { - private final static Log LOG = LogFactory.getLog(DruidConnectionHolder.class); - + + private final static Log LOG = LogFactory.getLog(DruidConnectionHolder.class); + private final DruidAbstractDataSource dataSource; private final Connection conn; private final List connectionEventListeners = new CopyOnWriteArrayList(); @@ -60,6 +60,7 @@ public final class DruidConnectionHolder { private int underlyingHoldability; private int underlyingTransactionIsolation; private boolean underlyingAutoCommit; + private boolean discard = false; public DruidConnectionHolder(DruidAbstractDataSource dataSource, Connection conn) throws SQLException{ @@ -167,6 +168,17 @@ public final class DruidConnectionHolder { return statementPool; } + public PreparedStatementPool getStatementPoolDirect() { + return statementPool; + } + + public void clearStatementCache() { + if (this.statementPool == null) { + return; + } + this.statementPool.clear(); + } + public DruidAbstractDataSource getDataSource() { return dataSource; } @@ -218,13 +230,21 @@ public final class DruidConnectionHolder { for (Object item : statementTrace.toArray()) { Statement stmt = (Statement) item; - JdbcUtils.close(stmt); + stmt.close(); } statementTrace.clear(); conn.clearWarnings(); } + public boolean isDiscard() { + return discard; + } + + public void setDiscard(boolean discard) { + this.discard = discard; + } + public String toString() { StringBuilder buf = new StringBuilder(); diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index ffb6c3feac..89961fe4ff 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -575,7 +575,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat if (!(isTestOnBorrow() || isTestOnReturn() || isTestWhileIdle())) { return; } - + if (this.validConnectionChecker != null) { return; } @@ -900,6 +900,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } } this.discardConnection(holder.getConnection()); + holder.setDiscard(true); pooledConnection.disable(t); } @@ -988,22 +989,14 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat lock.unlock(); } } catch (Throwable e) { - JdbcUtils.close(physicalConnection); + holder.clearStatementCache(); - try { - lock.lockInterruptibly(); - } catch (InterruptedException interruptEx) { - throw new SQLException("interrupt", interruptEx); + if (!holder.isDiscard()) { + this.discardConnection(physicalConnection); + holder.setDiscard(true); } - try { - activeCount--; - closeCount++; - } finally { - lock.unlock(); - } - - throw new SQLException("recyle error", e); + LOG.error("recyle error", e); } } diff --git a/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java b/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java index 7603766282..54225a424d 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java +++ b/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java @@ -149,6 +149,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql. try { rawStatement.clearParameters(); } catch (SQLException ex) { + this.handleException(ex); if (rawStatement.getConnection().isClosed()) { return; } @@ -187,6 +188,10 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql. } public void disable(Throwable error) { + if (this.holder != null) { + this.holder.clearStatementCache(); + } + this.traceEnable = false; this.holder = null; this.transactionInfo = null; @@ -292,7 +297,8 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql. } if (!this.abandoned) { - holder.getDataSource().recycle(this); + DruidAbstractDataSource dataSource = holder.getDataSource(); + dataSource.recycle(this); } this.holder = null; diff --git a/src/main/java/com/alibaba/druid/pool/DruidPooledPreparedStatement.java b/src/main/java/com/alibaba/druid/pool/DruidPooledPreparedStatement.java index 0e77d11ce9..e6344bba67 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidPooledPreparedStatement.java +++ b/src/main/java/com/alibaba/druid/pool/DruidPooledPreparedStatement.java @@ -163,26 +163,33 @@ public class DruidPooledPreparedStatement extends DruidPooledStatement implement return; } + boolean connectionClosed = this.conn.isClosed(); // Reset the defaults - if (defaultMaxFieldSize != currentMaxFieldSize) { - stmt.setMaxFieldSize(defaultMaxFieldSize); - currentMaxFieldSize = defaultMaxFieldSize; - } - if (defaultMaxRows != currentMaxRows) { - stmt.setMaxRows(defaultMaxRows); - currentMaxRows = defaultMaxRows; - } - if (defaultQueryTimeout != currentQueryTimeout) { - stmt.setQueryTimeout(defaultQueryTimeout); - currentQueryTimeout = defaultQueryTimeout; - } - if (defaultFetchDirection != currentFetchDirection) { - stmt.setFetchDirection(defaultFetchDirection); - currentFetchDirection = defaultFetchDirection; - } - if (defaultFetchSize != currentFetchSize) { - stmt.setFetchSize(defaultFetchSize); - currentFetchSize = defaultFetchSize; + if (!connectionClosed) { + try { + if (defaultMaxFieldSize != currentMaxFieldSize) { + stmt.setMaxFieldSize(defaultMaxFieldSize); + currentMaxFieldSize = defaultMaxFieldSize; + } + if (defaultMaxRows != currentMaxRows) { + stmt.setMaxRows(defaultMaxRows); + currentMaxRows = defaultMaxRows; + } + if (defaultQueryTimeout != currentQueryTimeout) { + stmt.setQueryTimeout(defaultQueryTimeout); + currentQueryTimeout = defaultQueryTimeout; + } + if (defaultFetchDirection != currentFetchDirection) { + stmt.setFetchDirection(defaultFetchDirection); + currentFetchDirection = defaultFetchDirection; + } + if (defaultFetchSize != currentFetchSize) { + stmt.setFetchSize(defaultFetchSize); + currentFetchSize = defaultFetchSize; + } + } catch (Exception e) { + this.conn.handleException(e); + } } conn.closePoolableStatement(this); @@ -1034,16 +1041,16 @@ public class DruidPooledPreparedStatement extends DruidPooledStatement implement } } - + @Override public boolean isWrapperFor(Class iface) throws SQLException { if (iface == PreparedStatementHolder.class) { return true; } - + return super.isWrapperFor(iface); } - + @SuppressWarnings("unchecked") public T unwrap(Class iface) throws SQLException { if (iface == PreparedStatementHolder.class) { diff --git a/src/main/java/com/alibaba/druid/pool/PreparedStatementPool.java b/src/main/java/com/alibaba/druid/pool/PreparedStatementPool.java index f397de07b5..bad2d014e1 100644 --- a/src/main/java/com/alibaba/druid/pool/PreparedStatementPool.java +++ b/src/main/java/com/alibaba/druid/pool/PreparedStatementPool.java @@ -89,11 +89,11 @@ public class PreparedStatementPool { PreparedStatementKey key = stmtHolder.getKey(); PreparedStatementHolder oldStmtHolder = map.put(key, stmtHolder); - + if (oldStmtHolder == stmtHolder) { return; } - + if (oldStmtHolder != null) { oldStmtHolder.setPooling(false); closeRemovedStatement(oldStmtHolder); @@ -104,25 +104,27 @@ public class PreparedStatementPool { } stmtHolder.setPooling(true); - + if (LOG.isDebugEnabled()) { String message = null; if (stmtHolder.getStatement() instanceof PreparedStatementProxy) { PreparedStatementProxy stmtProxy = (PreparedStatementProxy) stmtHolder.getStatement(); if (stmtProxy instanceof CallableStatementProxy) { - message = "{conn-" + stmtProxy.getConnectionProxy().getId() + ", cstmt-" + stmtProxy.getId() + "} enter cache"; + message = "{conn-" + stmtProxy.getConnectionProxy().getId() + ", cstmt-" + stmtProxy.getId() + + "} enter cache"; } else { - message = "{conn-" + stmtProxy.getConnectionProxy().getId() + ", pstmt-" + stmtProxy.getId() + "} enter cache"; + message = "{conn-" + stmtProxy.getConnectionProxy().getId() + ", pstmt-" + stmtProxy.getId() + + "} enter cache"; } } else { message = "stmt enter cache"; } - + LOG.debug(message); } } - public void clear() throws SQLException { + public void clear() { Iterator> iter = map.entrySet().iterator(); while (iter.hasNext()) { Entry entry = iter.next(); @@ -133,30 +135,36 @@ public class PreparedStatementPool { } } - public void closeRemovedStatement(PreparedStatementHolder holder) throws SQLException { + public void closeRemovedStatement(PreparedStatementHolder holder) { if (LOG.isDebugEnabled()) { String message = null; if (holder.getStatement() instanceof PreparedStatementProxy) { PreparedStatementProxy stmtProxy = (PreparedStatementProxy) holder.getStatement(); if (stmtProxy instanceof CallableStatementProxy) { - message = "{conn-" + stmtProxy.getConnectionProxy().getId() + ", cstmt-" + stmtProxy.getId() + "} exit cache"; + message = "{conn-" + stmtProxy.getConnectionProxy().getId() + ", cstmt-" + stmtProxy.getId() + + "} exit cache"; } else { - message = "{conn-" + stmtProxy.getConnectionProxy().getId() + ", pstmt-" + stmtProxy.getId() + "} exit cache"; + message = "{conn-" + stmtProxy.getConnectionProxy().getId() + ", pstmt-" + stmtProxy.getId() + + "} exit cache"; } } else { message = "stmt exit cache"; } - + LOG.debug(message); } - + holder.setPooling(false); if (holder.isInUse()) { return; } if (holder.isEnterOracleImplicitCache()) { - OracleUtils.exitImplicitCacheToClose(holder.getStatement()); + try { + OracleUtils.exitImplicitCacheToClose(holder.getStatement()); + } catch (Exception ex) { + LOG.error("exitImplicitCacheToClose error", ex); + } } dataSource.closePreapredStatement(holder); } @@ -181,11 +189,7 @@ public class PreparedStatementPool { boolean remove = (size() > dataSource.getMaxPoolPreparedStatementPerConnectionSize()); if (remove) { - try { - closeRemovedStatement(eldest.getValue()); - } catch (SQLException e) { - LOG.error("closeStatement error", e); - } + closeRemovedStatement(eldest.getValue()); } return remove; diff --git a/src/main/java/com/alibaba/druid/util/jdbc/ConnectionBase.java b/src/main/java/com/alibaba/druid/util/jdbc/ConnectionBase.java index 5a1bae8bb2..3725e55873 100644 --- a/src/main/java/com/alibaba/druid/util/jdbc/ConnectionBase.java +++ b/src/main/java/com/alibaba/druid/util/jdbc/ConnectionBase.java @@ -121,4 +121,5 @@ public abstract class ConnectionBase implements Connection { public boolean isReadOnly() throws SQLException { return readOnly; } + } diff --git a/src/main/java/com/alibaba/druid/util/jdbc/StatementBase.java b/src/main/java/com/alibaba/druid/util/jdbc/StatementBase.java index 9f4d7d36e0..6c7ce8a6c3 100644 --- a/src/main/java/com/alibaba/druid/util/jdbc/StatementBase.java +++ b/src/main/java/com/alibaba/druid/util/jdbc/StatementBase.java @@ -22,28 +22,29 @@ import java.sql.SQLFeatureNotSupportedException; import java.sql.SQLWarning; import java.sql.Statement; +import com.alibaba.druid.mock.MockConnection; import com.alibaba.druid.mock.MockConnectionClosedException; public abstract class StatementBase implements Statement { - private Connection connection; - private int fetchDirection; - private int fetchSize; - private int resultSetType; - private int resultSetConcurrency; - private int resultSetHoldability; - private int maxFieldSize; - private int maxRows; - private int queryTimeout; - private boolean escapeProcessing; - private String cursorName; - private SQLWarning warnings; - private int updateCount; - protected boolean closed = false; - private boolean poolable; + private Connection connection; + private int fetchDirection; + private int fetchSize; + private int resultSetType; + private int resultSetConcurrency; + private int resultSetHoldability; + private int maxFieldSize; + private int maxRows; + private int queryTimeout; + private boolean escapeProcessing; + private String cursorName; + private SQLWarning warnings; + private int updateCount; + protected boolean closed = false; + private boolean poolable; - protected ResultSet generatedKeys; - protected ResultSet resultSet; + protected ResultSet generatedKeys; + protected ResultSet resultSet; public StatementBase(Connection connection){ super(); @@ -62,9 +63,13 @@ public abstract class StatementBase implements Statement { if (closed) { throw new SQLException(); } - - if (this.connection != null && this.connection.isClosed()) { - throw new MockConnectionClosedException(); + + if (this.connection != null) { + if (this.connection instanceof MockConnection) { + ((MockConnection) this.connection).checkState(); + } else if (this.connection.isClosed()) { + throw new MockConnectionClosedException(); + } } } diff --git a/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest.java b/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest.java new file mode 100644 index 0000000000..8cf4571d66 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest.java @@ -0,0 +1,75 @@ +package com.alibaba.druid.bvt.pool.exception; + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.pool.DruidPooledConnection; +import com.alibaba.druid.pool.vendor.OracleExceptionSorter; +import com.alibaba.druid.test.util.OracleMockDriver; +import com.alibaba.druid.util.JdbcUtils; + +public class OracleExceptionSorterTest extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + + dataSource.setExceptionSorter(new OracleExceptionSorter()); + + dataSource.setDriver(new OracleMockDriver()); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setPoolPreparedStatements(true); + dataSource.setMaxOpenPreparedStatements(100); + dataSource.setFilters("log4j"); + } + + protected void tearDowN() throws Exception { + JdbcUtils.close(dataSource); + } + + public void test_connect() throws Exception { + String sql = "SELECT 1"; + { + DruidPooledConnection conn = dataSource.getConnection(); + + PreparedStatement pstmt = conn.prepareStatement(sql); + pstmt.execute(); + pstmt.close(); + conn.close(); + } + + DruidPooledConnection conn = dataSource.getConnection(); + PreparedStatement pstmt = conn.prepareStatement(sql); + pstmt.setFetchSize(1000); + + SQLException exception = new SQLException("xx", "xxx", 28); + boolean fatal = false; + try { + conn.handleException(exception); + } catch (SQLException ex) { + fatal = true; + } + Assert.assertTrue(fatal); + + pstmt.close(); + + SQLException commetError = null; + try { + conn.commit(); + } catch (SQLException ex) { + commetError = ex; + } + + Assert.assertNotNull(commetError); + Assert.assertSame(exception, commetError.getCause()); + + conn.close(); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_closeConn.java b/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_closeConn.java new file mode 100644 index 0000000000..57f7c84584 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_closeConn.java @@ -0,0 +1,67 @@ +package com.alibaba.druid.bvt.pool.exception; + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.mock.MockConnection; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.pool.DruidPooledConnection; +import com.alibaba.druid.pool.vendor.OracleExceptionSorter; +import com.alibaba.druid.test.util.OracleMockDriver; +import com.alibaba.druid.util.JdbcUtils; + +public class OracleExceptionSorterTest_closeConn extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + + dataSource.setExceptionSorter(new OracleExceptionSorter()); + + dataSource.setDriver(new OracleMockDriver()); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setPoolPreparedStatements(true); + dataSource.setMaxOpenPreparedStatements(100); + } + + protected void tearDowN() throws Exception { + JdbcUtils.close(dataSource); + } + + public void test_connect() throws Exception { + String sql = "SELECT 1"; + { + DruidPooledConnection conn = dataSource.getConnection(); + + PreparedStatement pstmt = conn.prepareStatement(sql); + pstmt.execute(); + pstmt.close(); + conn.close(); + + Assert.assertEquals(0, dataSource.getActiveCount()); + Assert.assertEquals(1, dataSource.getPoolingCount()); + Assert.assertEquals(1, dataSource.getCreateCount()); + } + + DruidPooledConnection conn = dataSource.getConnection(); + MockConnection mockConn = conn.unwrap(MockConnection.class); + Assert.assertNotNull(mockConn); + + PreparedStatement pstmt = conn.prepareStatement(sql); + pstmt.setFetchSize(1000); + + SQLException exception = new SQLException("xx", "xxx", 28); + mockConn.setError(exception); + + conn.close(); + Assert.assertEquals(0, dataSource.getActiveCount()); + Assert.assertEquals(1, dataSource.getPoolingCount()); + Assert.assertEquals(2, dataSource.getCreateCount()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_closeConn_1.java b/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_closeConn_1.java new file mode 100644 index 0000000000..4b5fc9e9a0 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_closeConn_1.java @@ -0,0 +1,66 @@ +package com.alibaba.druid.bvt.pool.exception; + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.mock.MockConnection; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.pool.DruidPooledConnection; +import com.alibaba.druid.pool.vendor.OracleExceptionSorter; +import com.alibaba.druid.test.util.OracleMockDriver; +import com.alibaba.druid.util.JdbcUtils; + +public class OracleExceptionSorterTest_closeConn_1 extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + + dataSource.setExceptionSorter(new OracleExceptionSorter()); + + dataSource.setDriver(new OracleMockDriver()); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setPoolPreparedStatements(true); + dataSource.setMaxOpenPreparedStatements(100); + } + + protected void tearDowN() throws Exception { + JdbcUtils.close(dataSource); + } + + public void test_connect() throws Exception { + String sql = "SELECT 1"; + { + DruidPooledConnection conn = dataSource.getConnection(); + + PreparedStatement pstmt = conn.prepareStatement(sql); + pstmt.execute(); + pstmt.close(); + conn.close(); + + Assert.assertEquals(0, dataSource.getActiveCount()); + Assert.assertEquals(1, dataSource.getPoolingCount()); + Assert.assertEquals(1, dataSource.getCreateCount()); + } + + DruidPooledConnection conn = dataSource.getConnection(); + MockConnection mockConn = conn.unwrap(MockConnection.class); + Assert.assertNotNull(mockConn); + + conn.prepareStatement(sql); + + SQLException exception = new SQLException("xx", "xxx", 28); + mockConn.setError(exception); + + conn.close(); + Assert.assertEquals(0, dataSource.getActiveCount()); + Assert.assertEquals(1, dataSource.getPoolingCount()); + Assert.assertEquals(2, dataSource.getCreateCount()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_closeConn_2.java b/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_closeConn_2.java new file mode 100644 index 0000000000..e130b09da1 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_closeConn_2.java @@ -0,0 +1,66 @@ +package com.alibaba.druid.bvt.pool.exception; + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.mock.MockConnection; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.pool.DruidPooledConnection; +import com.alibaba.druid.pool.vendor.OracleExceptionSorter; +import com.alibaba.druid.test.util.OracleMockDriver; +import com.alibaba.druid.util.JdbcUtils; + +public class OracleExceptionSorterTest_closeConn_2 extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + + dataSource.setExceptionSorter(new OracleExceptionSorter()); + + dataSource.setDriver(new OracleMockDriver()); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setPoolPreparedStatements(true); + dataSource.setMaxOpenPreparedStatements(100); + } + + protected void tearDowN() throws Exception { + JdbcUtils.close(dataSource); + } + + public void test_connect() throws Exception { + String sql = "SELECT 1"; + { + DruidPooledConnection conn = dataSource.getConnection(); + + PreparedStatement pstmt = conn.prepareStatement(sql); + pstmt.execute(); + pstmt.close(); + conn.close(); + + Assert.assertEquals(0, dataSource.getActiveCount()); + Assert.assertEquals(1, dataSource.getPoolingCount()); + Assert.assertEquals(1, dataSource.getCreateCount()); + } + + DruidPooledConnection conn = dataSource.getConnection(); + MockConnection mockConn = conn.unwrap(MockConnection.class); + Assert.assertNotNull(mockConn); + + conn.setAutoCommit(false); + + SQLException exception = new SQLException("xx", "xxx", 28); + mockConn.setError(exception); + + conn.close(); + Assert.assertEquals(0, dataSource.getActiveCount()); + Assert.assertEquals(1, dataSource.getPoolingCount()); + Assert.assertEquals(2, dataSource.getCreateCount()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_closeConn_3.java b/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_closeConn_3.java new file mode 100644 index 0000000000..6502b9e672 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_closeConn_3.java @@ -0,0 +1,67 @@ +package com.alibaba.druid.bvt.pool.exception; + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.mock.MockConnection; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.pool.DruidPooledConnection; +import com.alibaba.druid.pool.vendor.OracleExceptionSorter; +import com.alibaba.druid.test.util.OracleMockDriver; +import com.alibaba.druid.util.JdbcUtils; + +public class OracleExceptionSorterTest_closeConn_3 extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + + dataSource.setExceptionSorter(new OracleExceptionSorter()); + + dataSource.setDriver(new OracleMockDriver()); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setPoolPreparedStatements(true); + dataSource.setMaxOpenPreparedStatements(100); + } + + protected void tearDowN() throws Exception { + JdbcUtils.close(dataSource); + } + + public void test_connect() throws Exception { + String sql = "SELECT 1"; + { + DruidPooledConnection conn = dataSource.getConnection(); + + PreparedStatement pstmt = conn.prepareStatement(sql); + pstmt.execute(); + pstmt.close(); + conn.close(); + + Assert.assertEquals(0, dataSource.getActiveCount()); + Assert.assertEquals(1, dataSource.getPoolingCount()); + Assert.assertEquals(1, dataSource.getCreateCount()); + } + + DruidPooledConnection conn = dataSource.getConnection(); + MockConnection mockConn = conn.unwrap(MockConnection.class); + Assert.assertNotNull(mockConn); + + conn.setAutoCommit(false); + conn.setReadOnly(false); + + SQLException exception = new SQLException("xx", "xxx", 28); + mockConn.setError(exception); + + conn.close(); + Assert.assertEquals(0, dataSource.getActiveCount()); + Assert.assertEquals(1, dataSource.getPoolingCount()); + Assert.assertEquals(2, dataSource.getCreateCount()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_closeStmt.java b/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_closeStmt.java new file mode 100644 index 0000000000..93b1e6460c --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_closeStmt.java @@ -0,0 +1,79 @@ +package com.alibaba.druid.bvt.pool.exception; + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.mock.MockConnection; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.pool.DruidPooledConnection; +import com.alibaba.druid.pool.vendor.OracleExceptionSorter; +import com.alibaba.druid.test.util.OracleMockDriver; +import com.alibaba.druid.util.JdbcUtils; + +public class OracleExceptionSorterTest_closeStmt extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + + dataSource.setExceptionSorter(new OracleExceptionSorter()); + + dataSource.setDriver(new OracleMockDriver()); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setPoolPreparedStatements(true); + dataSource.setMaxOpenPreparedStatements(100); + } + + protected void tearDowN() throws Exception { + JdbcUtils.close(dataSource); + } + + public void test_connect() throws Exception { + String sql = "SELECT 1"; + { + DruidPooledConnection conn = dataSource.getConnection(); + + PreparedStatement pstmt = conn.prepareStatement(sql); + pstmt.execute(); + pstmt.close(); + conn.close(); + } + + DruidPooledConnection conn = dataSource.getConnection(); + MockConnection mockConn = conn.unwrap(MockConnection.class); + Assert.assertNotNull(mockConn); + + PreparedStatement pstmt = conn.prepareStatement(sql); + pstmt.setFetchSize(1000); + + SQLException exception = new SQLException("xx", "xxx", 28); + mockConn.setError(exception); + + SQLException closedErrror = null; + try { + pstmt.close(); + } catch (SQLException ex) { + closedErrror = ex; + } + Assert.assertNotNull(closedErrror); + Assert.assertSame(exception, closedErrror); + + SQLException commetError = null; + try { + conn.commit(); + } catch (SQLException ex) { + commetError = ex; + } + + Assert.assertNotNull(commetError); + Assert.assertSame(exception, commetError.getCause()); + + conn.close(); + } + +}