optimized for oracle 10

This commit is contained in:
wenshao
2012-01-06 10:15:46 +08:00
parent 00f0168dc0
commit cb7d672b13
16 changed files with 322 additions and 290 deletions
@@ -211,7 +211,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
protected boolean isOracle = false;
protected boolean useOracleImplicitCache = false;
protected boolean useOracleImplicitCache = true;
public boolean isOracle() {
return isOracle;
@@ -229,7 +229,16 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
}
public void setUseOracleImplicitCache(boolean useOracleImplicitCache) {
this.useOracleImplicitCache = useOracleImplicitCache;
if (this.useOracleImplicitCache != useOracleImplicitCache) {
this.useOracleImplicitCache = useOracleImplicitCache;
boolean isOracleDriver10 = isOracle() && this.driver != null && this.driver.getMajorVersion() == 10;
if (isOracleDriver10) {
this.getConnectProperties().setProperty("oracle.jdbc.FreeMemoryOnEnterImplicitCache", "true");
} else {
this.getConnectProperties().remove("oracle.jdbc.FreeMemoryOnEnterImplicitCache");
}
}
}
public Throwable getLastCreateError() {
@@ -295,6 +295,10 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
throw new SQLException("not support oracle driver " + driver.getMajorVersion() + "."
+ driver.getMinorVersion());
}
if (driver.getMajorVersion() == 10 && isUseOracleImplicitCache()) {
this.getConnectProperties().setProperty("oracle.jdbc.FreeMemoryOnEnterImplicitCache", "true");
}
}
String realDriverClassName = driver.getClass().getName();
@@ -1334,7 +1338,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
@Override
public String getVersion() {
return VERSION.MajorVersion + "." + VERSION.MinorVersion + "." + VERSION.RevisionVersion + "-2011-12-27 14:45";
return VERSION.MajorVersion + "." + VERSION.MinorVersion + "." + VERSION.RevisionVersion + "-2012-1-6 10:14";
}
}
@@ -1,21 +1,39 @@
package com.alibaba.druid.pool.vendor;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.alibaba.druid.logging.Log;
import com.alibaba.druid.logging.LogFactory;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.alibaba.druid.pool.ValidConnectionChecker;
import com.alibaba.druid.util.MySqlUtils;
import com.alibaba.druid.proxy.jdbc.ConnectionProxy;
import com.alibaba.druid.util.DruidLoaderUtils;
import com.alibaba.druid.util.JdbcUtils;
public class MySqlValidConnectionChecker implements ValidConnectionChecker, Serializable {
private static final long serialVersionUID = 1L;
private static final Log LOG = LogFactory.getLog(MySqlValidConnectionChecker.class);
private static final long serialVersionUID = 1L;
private static final Log LOG = LogFactory.getLog(MySqlValidConnectionChecker.class);
private Class<?> clazz;
private Method ping;
private boolean driverHasPingMethod = false;
public MySqlValidConnectionChecker(){
try {
clazz = DruidLoaderUtils.loadClass("com.mysql.jdbc.Connection");
ping = clazz.getMethod("ping");
if (ping != null) {
driverHasPingMethod = true;
}
} catch (Exception e) {
LOG.warn("Cannot resolve com.mysq.jdbc.Connection.ping method. Will use 'SELECT 1' instead.", e);
}
}
public boolean isValidConnection(Connection conn, String valiateQuery, int validationQueryTimeout) {
@@ -32,12 +50,41 @@ public class MySqlValidConnectionChecker implements ValidConnectionChecker, Seri
return true;
}
if (driverHasPingMethod) {
if (conn instanceof DruidPooledConnection) {
conn = ((DruidPooledConnection) conn).getConnection();
}
if (conn instanceof ConnectionProxy) {
conn = ((ConnectionProxy) conn).getRawObject();
}
if (clazz.isAssignableFrom(conn.getClass())) {
try {
ping.invoke(conn);
return true;
} catch (Exception e) {
LOG.warn("Unexpected error in ping", e);
return false;
}
}
}
Statement stmt = null;
ResultSet rs = null;
try {
MySqlUtils.ping(conn);
stmt = conn.createStatement();
stmt.setQueryTimeout(validationQueryTimeout);
rs = stmt.executeQuery(valiateQuery);
return true;
} catch (SQLException e) {
return false;
} catch (Exception e) {
LOG.warn("Unexpected error in ping", e);
return false;
} finally {
JdbcUtils.close(rs);
JdbcUtils.close(stmt);
}
}
@@ -22,24 +22,37 @@
package com.alibaba.druid.pool.vendor;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.alibaba.druid.logging.Log;
import com.alibaba.druid.logging.LogFactory;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.alibaba.druid.pool.ValidConnectionChecker;
import com.alibaba.druid.proxy.jdbc.ConnectionProxy;
import com.alibaba.druid.util.OracleUtils;
import com.alibaba.druid.util.DruidLoaderUtils;
import com.alibaba.druid.util.JdbcUtils;
public class OracleValidConnectionChecker implements ValidConnectionChecker, Serializable {
private static final long serialVersionUID = -2227528634302168877L;
private static final long serialVersionUID = -2227528634302168877L;
private static final Log LOG = LogFactory.getLog(OracleValidConnectionChecker.class);
private static final Log LOG = LogFactory.getLog(OracleValidConnectionChecker.class);
private final Class<?> clazz;
private final Method ping;
private final static Object[] params = new Object[] { new Integer(5000) };
public OracleValidConnectionChecker(){
try {
clazz = DruidLoaderUtils.loadClass("oracle.jdbc.driver.OracleConnection");
ping = clazz.getMethod("pingDatabase", new Class[] { Integer.TYPE });
} catch (Exception e) {
throw new RuntimeException("Unable to resolve pingDatabase method:", e);
}
}
public boolean isValidConnection(Connection conn, String valiateQuery, int validationQueryTimeout) {
@@ -65,14 +78,33 @@ public class OracleValidConnectionChecker implements ValidConnectionChecker, Ser
conn = ((ConnectionProxy) conn).getRawObject();
}
int status = OracleUtils.pingDatabase(conn);
// unwrap
if (clazz.isAssignableFrom(conn.getClass())) {
Integer status = (Integer) ping.invoke(conn, params);
// Error
if (status < 0) {
return false;
// Error
if (status.intValue() < 0) {
return false;
}
return true;
}
return true;
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery(valiateQuery);
return true;
} catch (SQLException e) {
return false;
} catch (Exception e) {
LOG.warn("Unexpected error in ping", e);
return false;
} finally {
JdbcUtils.close(rs);
JdbcUtils.close(stmt);
}
} catch (Exception e) {
LOG.warn("Unexpected error in pingDatabase", e);
}
@@ -88,7 +88,6 @@ public class OracleUtils {
oracleConn.setStatementCacheSize(size);
}
@SuppressWarnings("deprecation")
public static int pingDatabase(Connection conn) throws SQLException {
OracleConnection oracleConn = unwrap(conn);
return oracleConn.pingDatabase(1000);