Merge remote-tracking branch 'upstream/master'

This commit is contained in:
wenshao
2017-03-14 21:00:16 +08:00
4 changed files with 91 additions and 1 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright 1999-2016 Alibaba Group Holding Ltd.
Copyright 1999-2017 Alibaba Group Holding Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -177,6 +177,12 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
stmt.getPreparedStatementHolder().setFetchRowPeak(stmt.getFetchRowPeak());
stmt.setClosed(true); // soft set close
} else if (stmt.isPooled() && holder.isPoolPreparedStatements()) {
// the PreparedStatement threw an exception
stmt.clearResultSet();
holder.removeTrace(stmt);
holder.getStatementPool().remove(stmt.getPreparedStatementHolder());
} else {
try {
//Connection behind the statement may be in invalid state, which will throw a SQLException.
@@ -72,6 +72,14 @@ public class PreparedStatementPool {
return holder;
}
public void remove(PreparedStatementHolder stmtHolder) throws SQLException {
if (stmtHolder == null) {
return;
}
map.remove(stmtHolder.key);
closeRemovedStatement(stmtHolder);
}
public void put(PreparedStatementHolder stmtHolder) throws SQLException {
PreparedStatement stmt = stmtHolder.statement;
@@ -0,0 +1,76 @@
package com.alibaba.druid.pool;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* 测试开启PSCache后关闭DruidPooledPreparedStatement时的情况
*
* @author DigitalSonic
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:com/alibaba/druid/pool/dataSource.xml")
public class ClosePoolableStatementTest {
@Autowired
private DruidDataSource dataSource;
private JdbcTemplate jdbcTemplate;
@Before
public void setUp() throws Exception {
dataSource.setPoolPreparedStatements(true);
dataSource.setMaxPoolPreparedStatementPerConnectionSize(5);
dataSource.init();
jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.execute("create table test (id int, val varchar(32), primary key (id))");
}
@After
public void tearDown() throws Exception {
jdbcTemplate.execute("drop table test");
}
/**
* 关注抛出异常后能否正确将PreparedStatement移出缓存,能正常执行后续SQL
*/
@Test
public void testClose() throws Exception {
insertData(1, "a");
try {
insertData(1, "a");
} catch (Exception e) {
assertTrue(e instanceof DuplicateKeyException);
}
try {
insertData(1, "a");
} catch (Exception e) {
assertTrue(e instanceof DuplicateKeyException);
assertEquals(-1, e.getMessage().indexOf("closed"));
}
}
private void insertData(final int id, final String val) {
jdbcTemplate.update("insert into test (id, val) values (?, ?)", new PreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps) throws SQLException {
ps.setInt(1, id);
ps.setString(2, val);
}
});
}
}