optimized for oracle

This commit is contained in:
wenshao
2012-01-02 00:17:39 +08:00
parent 028a1d4fb5
commit 7f7dd5e6bb
12 changed files with 247 additions and 113 deletions
@@ -143,6 +143,10 @@ public final class ConnectionHolder {
}
public boolean isPoolPreparedStatements() {
// if (dataSource.isOracle()) {
// return false;
// }
boolean poolPreparedStatements = dataSource.isPoolPreparedStatements();
if (poolPreparedStatements) {
boolean transaction = !isUnderlyingAutoCommit();
@@ -183,7 +183,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
protected final AtomicLong commitCount = new AtomicLong();
protected final AtomicLong startTransactionCount = new AtomicLong();
protected final AtomicLong rollbackCount = new AtomicLong();
protected final AtomicLong cachedPreparedStatementHitCount = new AtomicLong();
protected final AtomicLong cachedPreparedStatementHitCount = new AtomicLong();
protected final AtomicLong preparedStatementCount = new AtomicLong();
protected final AtomicLong closedPreparedStatementCount = new AtomicLong();
protected final AtomicLong cachedPreparedStatementCount = new AtomicLong();
@@ -209,6 +209,12 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
protected Throwable lastCreateError;
protected long lastCreateErrorTimeMillis;
protected boolean isOracle = false;
public boolean isOracle() {
return isOracle;
}
public Throwable getLastCreateError() {
return lastCreateError;
}
@@ -300,7 +306,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
public long getCachedPreparedStatementMissCount() {
return cachedPreparedStatementMissCount.get();
}
public long getCachedPreparedStatementAccessCount() {
return cachedPreparedStatementMissCount.get() + cachedPreparedStatementHitCount.get();
}
@@ -1238,6 +1244,14 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
dataSource.validateConnection(conn);
dataSource.createError = null;
// if (dataSource.isOracle() && dataSource.isPoolPreparedStatements()) {
// int cacheSize = dataSource.getMaxPoolPreparedStatementPerConnectionSize();
// if (cacheSize > 0) {
// OracleUtils.setImplicitCachingEnabled(conn, true);
// OracleUtils.setStatementCacheSize(conn, cacheSize);
// }
// }
} catch (SQLException ex) {
dataSource.createErrorCount++;
dataSource.createError = ex;
@@ -1457,8 +1471,6 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
public Date getCreatedTime() {
return createdTime;
}
public abstract boolean isOracle();
public abstract int getRawDriverMajorVersion();
@@ -108,8 +108,6 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
private String initStackTrace;
private boolean isOracle = false;
public DruidDataSource(){
}
@@ -290,9 +288,10 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
if ("oracle".equals(this.dbType)) {
isOracle = true;
if (driver.getMajorVersion() < 10) {
throw new SQLException("not support oracle driver " + driver.getMajorVersion() + "." + driver.getMinorVersion());
throw new SQLException("not support oracle driver " + driver.getMajorVersion() + "."
+ driver.getMinorVersion());
}
}
@@ -631,7 +630,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
}
public void clearStatementCache() {
public void clearStatementCache() throws SQLException {
lock.lock();
try {
for (int i = 0; i < poolingCount; ++i) {
@@ -1324,10 +1323,6 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
}
public boolean isOracle() {
return isOracle;
}
@Override
public String getVersion() {
return VERSION.MajorVersion + "." + VERSION.MinorVersion + "." + VERSION.RevisionVersion + "-2011-12-27 14:45";
@@ -15,6 +15,7 @@
*/
package com.alibaba.druid.pool;
import java.sql.SQLException;
import java.util.Date;
import javax.management.ObjectName;
@@ -68,5 +69,5 @@ public interface DruidDataSourceMBean extends DruidAbstractDataSourceMBean {
ObjectName getObjectName();
void clearStatementCache();
void clearStatementCache() throws SQLException;
}
@@ -44,7 +44,6 @@ import com.alibaba.druid.logging.Log;
import com.alibaba.druid.logging.LogFactory;
import com.alibaba.druid.pool.PoolablePreparedStatement.PreparedStatementKey;
import com.alibaba.druid.pool.PreparedStatementPool.MethodType;
import com.alibaba.druid.util.OracleUtils;
import com.alibaba.druid.util.TransactionInfo;
/**
@@ -118,18 +117,16 @@ public class PoolableConnection implements PooledConnection, Connection {
if (holder == null) {
return;
}
if (holder.isPoolPreparedStatements()) {
holder.getStatementPool().put(stmt.getPreparedStatementHolder());
stmt.clearResultSet();
holder.removeTrace(stmt);
stmt.getPreparedStatementHolder().setFetchRowPeak(stmt.getFetchRowPeak());
stmt.setClosed(true); // soft set close
if (stmt.getHitCount() < 1 && isOracle()) {
OracleUtils.clearDefines(stmt);
}
} else {
stmt.closeInternal();
holder.getDataSource().incrementClosedPreparedStatementCount();
@@ -200,9 +197,6 @@ public class PoolableConnection implements PooledConnection, Connection {
try {
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql));
holder.getDataSource().incrementPreparedStatementCount();
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
handleException(ex);
}
@@ -237,9 +231,6 @@ public class PoolableConnection implements PooledConnection, Connection {
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql, resultSetType,
resultSetConcurrency));
holder.getDataSource().incrementPreparedStatementCount();
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
handleException(ex);
}
@@ -275,9 +266,6 @@ public class PoolableConnection implements PooledConnection, Connection {
resultSetConcurrency,
resultSetHoldability));
holder.getDataSource().incrementPreparedStatementCount();
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
handleException(ex);
}
@@ -309,9 +297,6 @@ public class PoolableConnection implements PooledConnection, Connection {
try {
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql, columnIndexes));
holder.getDataSource().incrementPreparedStatementCount();
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
handleException(ex);
}
@@ -343,9 +328,6 @@ public class PoolableConnection implements PooledConnection, Connection {
try {
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql, columnNames));
holder.getDataSource().incrementPreparedStatementCount();
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
handleException(ex);
}
@@ -377,9 +359,6 @@ public class PoolableConnection implements PooledConnection, Connection {
try {
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql, autoGeneratedKeys));
holder.getDataSource().incrementPreparedStatementCount();
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
handleException(ex);
}
@@ -413,9 +392,6 @@ public class PoolableConnection implements PooledConnection, Connection {
try {
stmtHolder = new PreparedStatementHolder(key, conn.prepareCall(sql));
holder.getDataSource().incrementPreparedStatementCount();
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
handleException(ex);
}
@@ -451,9 +427,6 @@ public class PoolableConnection implements PooledConnection, Connection {
resultSetConcurrency,
resultSetHoldability));
holder.getDataSource().incrementPreparedStatementCount();
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
handleException(ex);
}
@@ -487,9 +460,6 @@ public class PoolableConnection implements PooledConnection, Connection {
stmtHolder = new PreparedStatementHolder(key,
conn.prepareCall(sql, resultSetType, resultSetConcurrency));
holder.getDataSource().incrementPreparedStatementCount();
if (poolPreparedStatements) {
holder.getStatementPool().put(stmtHolder);
}
} catch (SQLException ex) {
handleException(ex);
}
@@ -174,7 +174,7 @@ public class PoolablePreparedStatement extends PoolableStatement implements Prep
incrementExecuteCount();
transactionRecord(sql);
// oracleSetRowPrefetch();
oracleSetRowPrefetch();
try {
ResultSet rs = stmt.executeQuery();
@@ -463,11 +463,11 @@ public class PoolablePreparedStatement extends PoolableStatement implements Prep
int rowPrefetch;
if (fetchRowPeak <= 1) {
rowPrefetch = 1;
rowPrefetch = 2;
} else if (fetchRowPeak > holder.getDefaultRowPretch()) {
rowPrefetch = holder.getDefaultRowPretch();
} else {
rowPrefetch = fetchRowPeak;
rowPrefetch = fetchRowPeak + 1;
}
if (rowPrefetch != holder.getRowPrefetch()) {
@@ -22,13 +22,18 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import com.alibaba.druid.logging.Log;
import com.alibaba.druid.logging.LogFactory;
import com.alibaba.druid.pool.PoolablePreparedStatement.PreparedStatementKey;
import com.alibaba.druid.util.OracleUtils;
/**
* @author wenshao<szujobs@hotmail.com>
*/
public class PreparedStatementPool {
private final static Log LOG = LogFactory.getLog(PreparedStatementPool.class);
private final Map<PreparedStatementKey, PreparedStatementHolder> map;
private final DruidAbstractDataSource dataSource;
@@ -45,12 +50,13 @@ public class PreparedStatementPool {
M1, M2, M3, M4, M5, M6, Precall_1, Precall_2, Precall_3
}
public PreparedStatementHolder get(PreparedStatementKey key) {
public PreparedStatementHolder get(PreparedStatementKey key) throws SQLException {
PreparedStatementHolder holder = map.get(key);
if (holder != null) {
holder.incrementHitCount();
dataSource.incrementCachedPreparedStatementHitCount();
OracleUtils.exitImplicitCacheToActive(holder.getStatement());
} else {
dataSource.incrementCachedPreparedStatementMissCount();
}
@@ -65,9 +71,14 @@ public class PreparedStatementPool {
return;
}
if (dataSource.isOracle()) {
OracleUtils.enterImplicitCache(stmt);
}
PreparedStatementKey key = holder.getKey();
PreparedStatementHolder oldHolder = map.put(key, holder);
if (oldHolder != null) {
if (oldHolder != null && oldHolder != holder) {
dataSource.closePreapredStatement(oldHolder);
} else {
if (holder.getHitCount() == 0) {
@@ -75,20 +86,27 @@ public class PreparedStatementPool {
}
}
}
public void clear() {
public void clear() throws SQLException {
Iterator<Entry<PreparedStatementKey, PreparedStatementHolder>> iter = map.entrySet().iterator();
while (iter.hasNext()) {
Entry<PreparedStatementKey, PreparedStatementHolder> entry = iter.next();
dataSource.closePreapredStatement(entry.getValue());
dataSource.decrementCachedPreparedStatementCount();
dataSource.incrementCachedPreparedStatementDeleteCount();
closeStatement(entry.getValue());
iter.remove();
}
}
private void closeStatement(PreparedStatementHolder holder) throws SQLException {
if (dataSource.isOracle()) {
OracleUtils.exitImplicitCacheToClose(holder.getStatement());
}
dataSource.closePreapredStatement(holder);
dataSource.decrementCachedPreparedStatementCount();
dataSource.incrementCachedPreparedStatementDeleteCount();
}
public Map<PreparedStatementKey, PreparedStatementHolder> getMap() {
return map;
}
@@ -105,9 +123,11 @@ public class PreparedStatementPool {
boolean remove = (size() > dataSource.getMaxPoolPreparedStatementPerConnectionSize());
if (remove) {
dataSource.closePreapredStatement(eldest.getValue());
dataSource.decrementCachedPreparedStatementCount();
dataSource.incrementCachedPreparedStatementDeleteCount();
try {
closeStatement(eldest.getValue());
} catch (SQLException e) {
LOG.error("closeStatement error", e);
}
}
return remove;
@@ -2,13 +2,13 @@ package com.alibaba.druid.util;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleResultSet;
import oracle.jdbc.OracleStatement;
import oracle.jdbc.internal.OraclePreparedStatement;
import oracle.sql.ROWID;
import com.alibaba.druid.pool.PoolablePreparedStatement;
@@ -29,6 +29,29 @@ public class OracleUtils {
OracleStatement oracleStmt = stmt.unwrap(OracleStatement.class);
oracleStmt.setRowPrefetch(value);
}
public static void enterImplicitCache(PreparedStatement stmt) throws SQLException {
oracle.jdbc.internal.OraclePreparedStatement oracleStmt = unwrapInternal(stmt);
oracleStmt.enterImplicitCache();
}
public static void exitImplicitCacheToClose(PreparedStatement stmt) throws SQLException {
oracle.jdbc.internal.OraclePreparedStatement oracleStmt = unwrapInternal(stmt);
oracleStmt.exitImplicitCacheToClose();
}
public static void exitImplicitCacheToActive(PreparedStatement stmt) throws SQLException {
oracle.jdbc.internal.OraclePreparedStatement oracleStmt = unwrapInternal(stmt);
oracleStmt.exitImplicitCacheToActive();
}
public static OraclePreparedStatement unwrapInternal(PreparedStatement stmt) throws SQLException {
if (stmt instanceof OraclePreparedStatement) {
return (OraclePreparedStatement) stmt;
}
return stmt.unwrap(OraclePreparedStatement.class);
}
public static void setDefaultRowPrefetch(Connection conn, int value) throws SQLException {
OracleConnection oracleConn = unwrap(conn);
@@ -40,14 +63,34 @@ public class OracleUtils {
return oracleConn.getDefaultRowPrefetch();
}
public static void cancel(Connection conn) throws SQLException {
public static boolean getImplicitCachingEnabled(Connection conn) throws SQLException {
OracleConnection oracleConn = unwrap(conn);
oracleConn.cancel();
return oracleConn.getImplicitCachingEnabled();
}
public static int getStatementCacheSize(Connection conn) throws SQLException {
OracleConnection oracleConn = unwrap(conn);
return oracleConn.getStatementCacheSize();
}
public static void purgeImplicitCache(Connection conn) throws SQLException {
OracleConnection oracleConn = unwrap(conn);
oracleConn.purgeImplicitCache();
}
public static void setImplicitCachingEnabled(Connection conn, boolean cache) throws SQLException {
OracleConnection oracleConn = unwrap(conn);
oracleConn.setImplicitCachingEnabled(cache);
}
public static void setStatementCacheSize(Connection conn, int size) throws SQLException {
OracleConnection oracleConn = unwrap(conn);
oracleConn.setStatementCacheSize(size);
}
public static int pingDatabase(Connection conn) throws SQLException {
OracleConnection oracleConn = unwrap(conn);
return oracleConn.pingDatabase();
return oracleConn.pingDatabase(1000);
}
public static void openProxySession(Connection conn, int type, java.util.Properties prop) throws SQLException {