support sharePreparedStatements option

This commit is contained in:
wenshao
2011-12-28 17:49:55 +08:00
parent f80fb10be2
commit 0a2d5f43c8
6 changed files with 168 additions and 40 deletions
@@ -66,7 +66,7 @@ public final class ConnectionHolder {
this.defaultHoldability = conn.getHoldability();
this.defaultTransactionIsolation = conn.getTransactionIsolation();
this.defaultAutoCommit = conn.getAutoCommit();
this.underlyingAutoCommit = defaultAutoCommit;
this.underlyingHoldability = defaultHoldability;
this.underlyingTransactionIsolation = defaultTransactionIsolation;
@@ -143,7 +143,15 @@ public final class ConnectionHolder {
}
public boolean isPoolPreparedStatements() {
return dataSource.isPoolPreparedStatements();
boolean poolPreparedStatements = dataSource.isPoolPreparedStatements();
if (poolPreparedStatements) {
boolean transaction = !isUnderlyingAutoCommit();
if (transaction && !dataSource.isSharePreparedStatements()) {
poolPreparedStatements = false;
}
}
return poolPreparedStatements;
}
public Connection getConnection() {
@@ -119,6 +119,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
private boolean testOnReturn = DEFAULT_TEST_ON_RETURN;
private boolean testWhileIdle = DEFAULT_WHILE_IDLE;
protected boolean poolPreparedStatements = false;
protected boolean sharePreparedStatements = false;
protected int maxPoolPreparedStatementPerConnectionSize = 10;
protected boolean inited = false;
@@ -206,7 +207,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
if (transactionQueryTimeout <= 0) {
return queryTimeout;
}
return transactionQueryTimeout;
}
@@ -349,9 +350,21 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
}
public void setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize) {
if (maxPoolPreparedStatementPerConnectionSize > 0) {
this.poolPreparedStatements = true;
}
this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
}
public boolean isSharePreparedStatements() {
return sharePreparedStatements;
}
public void setSharePreparedStatements(boolean sharePreparedStatements) {
this.sharePreparedStatements = sharePreparedStatements;
}
public void incrementDupCloseCount() {
dupCloseCount.incrementAndGet();
}
@@ -436,7 +449,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
}
public void setMaxOpenPreparedStatements(int maxOpenPreparedStatements) {
this.maxPoolPreparedStatementPerConnectionSize = maxOpenPreparedStatements;
this.setMaxPoolPreparedStatementPerConnectionSize(maxOpenPreparedStatements);
}
public boolean isLogAbandoned() {
@@ -1044,9 +1057,9 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
void initStatement(PoolableConnection conn, Statement stmt) throws SQLException {
boolean transaction = !conn.getConnectionHolder().isUnderlyingAutoCommit();
int queryTimeout = transaction ? getTransactionQueryTimeout() : getQueryTimeout();
if (queryTimeout > 0) {
stmt.setQueryTimeout(queryTimeout);
}
@@ -44,7 +44,7 @@ public interface DruidAbstractDataSourceMBean {
long getStartTransactionCount();
int getQueryTimeout();
int getTransactionQueryTimeout();
String getValidationQuery();
@@ -66,13 +66,13 @@ public interface DruidAbstractDataSourceMBean {
List<String> getFilterClassNames();
boolean isTestOnBorrow();
void setTestOnBorrow(boolean testOnBorrow);
boolean isTestOnReturn();
boolean isTestWhileIdle();
void setTestWhileIdle(boolean testWhileIdle);
boolean isDefaultAutoCommit();
@@ -85,6 +85,8 @@ public interface DruidAbstractDataSourceMBean {
boolean isPoolPreparedStatements();
boolean isSharePreparedStatements();
long getMaxWait();
int getMinIdle();
@@ -102,7 +104,7 @@ public interface DruidAbstractDataSourceMBean {
long getRemoveAbandonedCount();
boolean isLogAbandoned();
void setLogAbandoned(boolean logAbandoned);
long getDupCloseCount();
@@ -167,11 +167,12 @@ public class PoolableConnection implements PooledConnection, Connection {
public PreparedStatement prepareStatement(String sql) throws SQLException {
checkOpen();
PreparedStatementHolder stmtHolder = null;
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.M1);
PreparedStatementHolder stmtHolder = null;
boolean poolPreparedStatements = holder.isPoolPreparedStatements();
if (holder.isPoolPreparedStatements()) {
if (poolPreparedStatements) {
stmtHolder = holder.getStatementPool().get(key);
}
@@ -179,7 +180,7 @@ public class PoolableConnection implements PooledConnection, Connection {
try {
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql));
holder.getDataSource().incrementPreparedStatementCount();
if (holder.isPoolPreparedStatements()) {
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
@@ -203,12 +204,13 @@ public class PoolableConnection implements PooledConnection, Connection {
throws SQLException {
checkOpen();
PreparedStatementHolder stmtHolder = null;
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.M2, resultSetType,
resultSetConcurrency);
PreparedStatementHolder stmtHolder = null;
boolean poolPreparedStatements = holder.isPoolPreparedStatements();
if (holder.isPoolPreparedStatements()) {
if (poolPreparedStatements) {
stmtHolder = holder.getStatementPool().get(key);
}
@@ -217,7 +219,7 @@ public class PoolableConnection implements PooledConnection, Connection {
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql, resultSetType,
resultSetConcurrency));
holder.getDataSource().incrementPreparedStatementCount();
if (holder.isPoolPreparedStatements()) {
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
@@ -241,12 +243,13 @@ public class PoolableConnection implements PooledConnection, Connection {
int resultSetHoldability) throws SQLException {
checkOpen();
PreparedStatementHolder stmtHolder = null;
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.M3, resultSetType,
resultSetConcurrency, resultSetHoldability);
PreparedStatementHolder stmtHolder = null;
boolean poolPreparedStatements = holder.isPoolPreparedStatements();
if (holder.isPoolPreparedStatements()) {
if (poolPreparedStatements) {
stmtHolder = holder.getStatementPool().get(key);
}
@@ -256,7 +259,7 @@ public class PoolableConnection implements PooledConnection, Connection {
resultSetConcurrency,
resultSetHoldability));
holder.getDataSource().incrementPreparedStatementCount();
if (holder.isPoolPreparedStatements()) {
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
@@ -279,10 +282,12 @@ public class PoolableConnection implements PooledConnection, Connection {
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
checkOpen();
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.M4, columnIndexes);
PreparedStatementHolder stmtHolder = null;
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.M4, columnIndexes);
if (holder.isPoolPreparedStatements()) {
boolean poolPreparedStatements = holder.isPoolPreparedStatements();
if (poolPreparedStatements) {
stmtHolder = holder.getStatementPool().get(key);
}
@@ -290,7 +295,7 @@ public class PoolableConnection implements PooledConnection, Connection {
try {
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql, columnIndexes));
holder.getDataSource().incrementPreparedStatementCount();
if (holder.isPoolPreparedStatements()) {
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
@@ -313,10 +318,12 @@ public class PoolableConnection implements PooledConnection, Connection {
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
checkOpen();
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.M5, columnNames);
PreparedStatementHolder stmtHolder = null;
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.M5, columnNames);
if (holder.isPoolPreparedStatements()) {
boolean poolPreparedStatements = holder.isPoolPreparedStatements();
if (poolPreparedStatements) {
stmtHolder = holder.getStatementPool().get(key);
}
@@ -324,7 +331,7 @@ public class PoolableConnection implements PooledConnection, Connection {
try {
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql, columnNames));
holder.getDataSource().incrementPreparedStatementCount();
if (holder.isPoolPreparedStatements()) {
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
@@ -347,10 +354,12 @@ public class PoolableConnection implements PooledConnection, Connection {
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
checkOpen();
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.M6, autoGeneratedKeys);
PreparedStatementHolder stmtHolder = null;
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.M6, autoGeneratedKeys);
if (holder.isPoolPreparedStatements()) {
boolean poolPreparedStatements = holder.isPoolPreparedStatements();
if (poolPreparedStatements) {
stmtHolder = holder.getStatementPool().get(key);
}
@@ -358,7 +367,7 @@ public class PoolableConnection implements PooledConnection, Connection {
try {
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql, autoGeneratedKeys));
holder.getDataSource().incrementPreparedStatementCount();
if (holder.isPoolPreparedStatements()) {
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
@@ -383,11 +392,12 @@ public class PoolableConnection implements PooledConnection, Connection {
public CallableStatement prepareCall(String sql) throws SQLException {
checkOpen();
PreparedStatementHolder stmtHolder = null;
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.Precall_1);
PreparedStatementHolder stmtHolder = null;
boolean poolPreparedStatements = holder.isPoolPreparedStatements();
if (holder.isPoolPreparedStatements()) {
if (poolPreparedStatements) {
stmtHolder = holder.getStatementPool().get(key);
}
@@ -395,7 +405,7 @@ public class PoolableConnection implements PooledConnection, Connection {
try {
stmtHolder = new PreparedStatementHolder(key, conn.prepareCall(sql));
holder.getDataSource().incrementPreparedStatementCount();
if (holder.isPoolPreparedStatements()) {
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
@@ -420,10 +430,12 @@ public class PoolableConnection implements PooledConnection, Connection {
checkOpen();
PreparedStatementHolder stmtHolder = null;
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.Precall_2, resultSetType,
resultSetConcurrency, resultSetHoldability);
if (holder.isPoolPreparedStatements()) {
boolean poolPreparedStatements = holder.isPoolPreparedStatements();
if (poolPreparedStatements) {
stmtHolder = holder.getStatementPool().get(key);
}
@@ -433,7 +445,7 @@ public class PoolableConnection implements PooledConnection, Connection {
resultSetConcurrency,
resultSetHoldability));
holder.getDataSource().incrementPreparedStatementCount();
if (holder.isPoolPreparedStatements()) {
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
@@ -457,10 +469,12 @@ public class PoolableConnection implements PooledConnection, Connection {
checkOpen();
PreparedStatementHolder stmtHolder = null;
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.Precall_3, resultSetType,
resultSetConcurrency);
if (holder.isPoolPreparedStatements()) {
boolean poolPreparedStatements = holder.isPoolPreparedStatements();
if (poolPreparedStatements) {
stmtHolder = holder.getStatementPool().get(key);
}
@@ -469,7 +483,7 @@ public class PoolableConnection implements PooledConnection, Connection {
stmtHolder = new PreparedStatementHolder(key,
conn.prepareCall(sql, resultSetType, resultSetConcurrency));
holder.getDataSource().incrementPreparedStatementCount();
if (holder.isPoolPreparedStatements()) {
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
@@ -0,0 +1,91 @@
package com.alibaba.druid.bvt.pool;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import junit.framework.Assert;
import junit.framework.TestCase;
import com.alibaba.druid.mock.MockPreparedStatement;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.stat.DruidDataSourceStatManager;
public class TestSharePreparedStatements extends TestCase {
protected void setUp() throws Exception {
Assert.assertEquals(0, DruidDataSourceStatManager.getInstance().getDataSourceList().size());
}
protected void tearDown() throws Exception {
Assert.assertEquals(0, DruidDataSourceStatManager.getInstance().getDataSourceList().size());
}
public void test_sharePreparedStatements() throws Exception {
// sharePreparedStatements
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mock:xxx");
dataSource.setMaxPoolPreparedStatementPerConnectionSize(30);
String sql = "SELECT 1";
MockPreparedStatement mockStmt = null;
{
Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql);
mockStmt = stmt.unwrap(MockPreparedStatement.class);
ResultSet rs = stmt.executeQuery();
rs.next();
rs.close();
stmt.close();
conn.close();
}
{
Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql);
Assert.assertEquals(mockStmt, stmt.unwrap(MockPreparedStatement.class));
ResultSet rs = stmt.executeQuery();
rs.next();
rs.close();
stmt.close();
conn.close();
}
{
Connection conn = dataSource.getConnection();
conn.setAutoCommit(false);
PreparedStatement stmt = conn.prepareStatement(sql);
Assert.assertEquals(true, mockStmt != stmt.unwrap(MockPreparedStatement.class));
ResultSet rs = stmt.executeQuery();
rs.next();
rs.close();
stmt.close();
conn.close();
}
{
Connection conn = dataSource.getConnection();
conn.setAutoCommit(false);
PreparedStatement stmt = conn.prepareStatement(sql);
Assert.assertEquals(true, mockStmt != stmt.unwrap(MockPreparedStatement.class));
ResultSet rs = stmt.executeQuery();
rs.next();
rs.close();
stmt.close();
conn.close();
}
dataSource.close();
}
}
@@ -19,8 +19,8 @@ public class PerfTest extends TestCase {
public void test_perf() throws Exception {
for (int i = 0; i < 10; ++i) {
// perf("SELECT * FROM my_table WHERE TRUNC(SYSDATE) = DATE '2002-10-03';");
perfOracle("SELECT * FROM T");
perfMySql("SELECT * FROM T");
perfOracle("SELECT a.ID, a.GMT_CREATE, a.GMT_MODIFIED, a.COMPANY_NAME, a.BIZ_TYPE , b.SERVICE_TYPE, b.SERVICE_LEVEL, b.BUSINESS_ROLE, a.STATUS, a.RECOMMENDED , a.COUNTRY, a.PROVINCE, a.CITY, a.ADDRESS, a.ZIP , a.LOGO_FILE, a.EMAIL, a.BRIEF_PROFILE, a.DOMAIN_ID, a.IS_PASS_AV , a.KEYWORDS, a.PROVIDE_PRODUCTS, a.PURCHASE_PRODUCTS, a.BRAND_NAME, a.PROMOTION_VALUE , a.OWNER_MEMBER_ID, a.OWNER_SEQ, a.EMPLOYEES_COUNT, a.ANNUAL_REVENUE, a.HOMEPAGE_URL , a.REG_ADDRESS, a.TRADE_REGION, a.TRADE_REGION_USER, a.REG_CAPITAL, a.OWNERSHIP_TYPE , a.ESTABLISHED_YEAR, a.PRINCIPAL, a.ANNUAL_PURCHASE, a.CERTIFICATION, a.CERTIFICATION_2 , a.CONTACT_MANUFACTURING, a.YEARS_OEM, b.STAGE, a.VIDEO_PATH, a.ABOUTUS_IMAGE_PATH , a.ABOUTUS_IMAGE_TITLE, a.CHINESE_NAME, a.IMAGE_VERSION FROM COMPANY a, VACCOUNT b WHERE a.ID = b.ID AND a.id IN (?)");
perfMySql("SELECT a.ID, a.GMT_CREATE, a.GMT_MODIFIED, a.COMPANY_NAME, a.BIZ_TYPE , b.SERVICE_TYPE, b.SERVICE_LEVEL, b.BUSINESS_ROLE, a.STATUS, a.RECOMMENDED , a.COUNTRY, a.PROVINCE, a.CITY, a.ADDRESS, a.ZIP , a.LOGO_FILE, a.EMAIL, a.BRIEF_PROFILE, a.DOMAIN_ID, a.IS_PASS_AV , a.KEYWORDS, a.PROVIDE_PRODUCTS, a.PURCHASE_PRODUCTS, a.BRAND_NAME, a.PROMOTION_VALUE , a.OWNER_MEMBER_ID, a.OWNER_SEQ, a.EMPLOYEES_COUNT, a.ANNUAL_REVENUE, a.HOMEPAGE_URL , a.REG_ADDRESS, a.TRADE_REGION, a.TRADE_REGION_USER, a.REG_CAPITAL, a.OWNERSHIP_TYPE , a.ESTABLISHED_YEAR, a.PRINCIPAL, a.ANNUAL_PURCHASE, a.CERTIFICATION, a.CERTIFICATION_2 , a.CONTACT_MANUFACTURING, a.YEARS_OEM, b.STAGE, a.VIDEO_PATH, a.ABOUTUS_IMAGE_PATH , a.ABOUTUS_IMAGE_TITLE, a.CHINESE_NAME, a.IMAGE_VERSION FROM COMPANY a, VACCOUNT b WHERE a.ID = b.ID AND a.id IN (?)");
// perf(loadSql("bvt/parser/oracle-23.txt"));
}
}