|
|
@ -15,84 +15,86 @@ |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
package com.fr.third.alibaba.druid.pool; |
|
|
|
package com.fr.third.alibaba.druid.pool; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import com.fr.third.alibaba.druid.DbType; |
|
|
|
|
|
|
|
import com.fr.third.alibaba.druid.pool.DruidAbstractDataSource.PhysicalConnectionInfo; |
|
|
|
|
|
|
|
import com.fr.third.alibaba.druid.proxy.jdbc.WrapperProxy; |
|
|
|
|
|
|
|
import com.fr.third.alibaba.druid.support.logging.Log; |
|
|
|
|
|
|
|
import com.fr.third.alibaba.druid.support.logging.LogFactory; |
|
|
|
|
|
|
|
import com.fr.third.alibaba.druid.util.JdbcUtils; |
|
|
|
|
|
|
|
import com.fr.third.alibaba.druid.util.Utils; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import javax.sql.ConnectionEventListener; |
|
|
|
|
|
|
|
import javax.sql.StatementEventListener; |
|
|
|
import java.sql.Connection; |
|
|
|
import java.sql.Connection; |
|
|
|
import java.sql.SQLException; |
|
|
|
import java.sql.SQLException; |
|
|
|
import java.sql.SQLFeatureNotSupportedException; |
|
|
|
|
|
|
|
import java.sql.Statement; |
|
|
|
import java.sql.Statement; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.ArrayList; |
|
|
|
|
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.Date; |
|
|
|
import java.util.Date; |
|
|
|
|
|
|
|
import java.util.HashSet; |
|
|
|
import java.util.List; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
import java.util.Set; |
|
|
|
import java.util.concurrent.CopyOnWriteArrayList; |
|
|
|
import java.util.concurrent.CopyOnWriteArrayList; |
|
|
|
import java.util.concurrent.locks.ReentrantLock; |
|
|
|
import java.util.concurrent.locks.ReentrantLock; |
|
|
|
|
|
|
|
|
|
|
|
import javax.sql.ConnectionEventListener; |
|
|
|
|
|
|
|
import javax.sql.StatementEventListener; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import com.fr.third.alibaba.druid.DbType; |
|
|
|
|
|
|
|
import com.fr.third.alibaba.druid.pool.DruidAbstractDataSource.PhysicalConnectionInfo; |
|
|
|
|
|
|
|
import com.fr.third.alibaba.druid.proxy.jdbc.WrapperProxy; |
|
|
|
|
|
|
|
import com.fr.third.alibaba.druid.support.logging.Log; |
|
|
|
|
|
|
|
import com.fr.third.alibaba.druid.support.logging.LogFactory; |
|
|
|
|
|
|
|
import com.fr.third.alibaba.druid.util.JdbcConstants; |
|
|
|
|
|
|
|
import com.fr.third.alibaba.druid.util.JdbcUtils; |
|
|
|
|
|
|
|
import com.fr.third.alibaba.druid.util.Utils; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* @author wenshao [szujobs@hotmail.com] |
|
|
|
* @author wenshao [szujobs@hotmail.com] |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public final class DruidConnectionHolder { |
|
|
|
public final class DruidConnectionHolder { |
|
|
|
private final static Log LOG = LogFactory.getLog(DruidConnectionHolder.class); |
|
|
|
private final static Log LOG = LogFactory.getLog(DruidConnectionHolder.class); |
|
|
|
public static boolean holdabilityUnsupported = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected final DruidAbstractDataSource dataSource; |
|
|
|
static Set<DbType> holdabilityUnsupportedDbTypes = new HashSet<>(Arrays.asList(DbType.sybase, DbType.db2, DbType.hive, DbType.odps)); |
|
|
|
protected final long connectionId; |
|
|
|
public static boolean holdabilityUnsupported = false; |
|
|
|
protected final Connection conn; |
|
|
|
|
|
|
|
|
|
|
|
protected final DruidAbstractDataSource dataSource; |
|
|
|
|
|
|
|
protected final long connectionId; |
|
|
|
|
|
|
|
protected final Connection conn; |
|
|
|
protected final List<ConnectionEventListener> connectionEventListeners = new CopyOnWriteArrayList<ConnectionEventListener>(); |
|
|
|
protected final List<ConnectionEventListener> connectionEventListeners = new CopyOnWriteArrayList<ConnectionEventListener>(); |
|
|
|
protected final List<StatementEventListener> statementEventListeners = new CopyOnWriteArrayList<StatementEventListener>(); |
|
|
|
protected final List<StatementEventListener> statementEventListeners = new CopyOnWriteArrayList<StatementEventListener>(); |
|
|
|
protected final long connectTimeMillis; |
|
|
|
protected final long connectTimeMillis; |
|
|
|
protected volatile long lastActiveTimeMillis; |
|
|
|
protected volatile long lastActiveTimeMillis; |
|
|
|
protected volatile long lastExecTimeMillis; |
|
|
|
protected volatile long lastExecTimeMillis; |
|
|
|
protected volatile long lastKeepTimeMillis; |
|
|
|
protected volatile long lastKeepTimeMillis; |
|
|
|
protected volatile long lastValidTimeMillis; |
|
|
|
protected volatile long lastValidTimeMillis; |
|
|
|
protected long useCount = 0; |
|
|
|
protected long useCount = 0; |
|
|
|
private long keepAliveCheckCount = 0; |
|
|
|
private long keepAliveCheckCount = 0; |
|
|
|
private long lastNotEmptyWaitNanos; |
|
|
|
private long lastNotEmptyWaitNanos; |
|
|
|
private final long createNanoSpan; |
|
|
|
private final long createNanoSpan; |
|
|
|
protected PreparedStatementPool statementPool; |
|
|
|
protected PreparedStatementPool statementPool; |
|
|
|
protected final List<Statement> statementTrace = new ArrayList<Statement>(2); |
|
|
|
protected final List<Statement> statementTrace = new ArrayList<Statement>(2); |
|
|
|
protected final boolean defaultReadOnly; |
|
|
|
protected final boolean defaultReadOnly; |
|
|
|
protected final int defaultHoldability; |
|
|
|
protected final int defaultHoldability; |
|
|
|
protected final int defaultTransactionIsolation; |
|
|
|
protected final int defaultTransactionIsolation; |
|
|
|
protected final boolean defaultAutoCommit; |
|
|
|
protected final boolean defaultAutoCommit; |
|
|
|
protected boolean underlyingReadOnly; |
|
|
|
protected boolean underlyingReadOnly; |
|
|
|
protected int underlyingHoldability; |
|
|
|
protected int underlyingHoldability; |
|
|
|
protected int underlyingTransactionIsolation; |
|
|
|
protected int underlyingTransactionIsolation; |
|
|
|
protected boolean underlyingAutoCommit; |
|
|
|
protected boolean underlyingAutoCommit; |
|
|
|
protected volatile boolean discard = false; |
|
|
|
protected volatile boolean discard = false; |
|
|
|
protected volatile boolean active = false; |
|
|
|
protected volatile boolean active = false; |
|
|
|
protected final Map<String, Object> variables; |
|
|
|
protected final Map<String, Object> variables; |
|
|
|
protected final Map<String, Object> globleVariables; |
|
|
|
protected final Map<String, Object> globleVariables; |
|
|
|
final ReentrantLock lock = new ReentrantLock(); |
|
|
|
final ReentrantLock lock = new ReentrantLock(); |
|
|
|
protected String initSchema; |
|
|
|
protected String initSchema; |
|
|
|
|
|
|
|
|
|
|
|
public DruidConnectionHolder(DruidAbstractDataSource dataSource, PhysicalConnectionInfo pyConnectInfo) |
|
|
|
public DruidConnectionHolder(DruidAbstractDataSource dataSource, PhysicalConnectionInfo pyConnectInfo) |
|
|
|
throws SQLException{ |
|
|
|
throws SQLException { |
|
|
|
this(dataSource, |
|
|
|
this(dataSource, |
|
|
|
pyConnectInfo.getPhysicalConnection(), |
|
|
|
pyConnectInfo.getPhysicalConnection(), |
|
|
|
pyConnectInfo.getConnectNanoSpan(), |
|
|
|
pyConnectInfo.getConnectNanoSpan(), |
|
|
|
pyConnectInfo.getVairiables(), |
|
|
|
pyConnectInfo.getVairiables(), |
|
|
|
pyConnectInfo.getGlobalVairiables()); |
|
|
|
pyConnectInfo.getGlobalVairiables()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public DruidConnectionHolder(DruidAbstractDataSource dataSource, Connection conn, long connectNanoSpan) |
|
|
|
public DruidConnectionHolder(DruidAbstractDataSource dataSource, Connection conn, long connectNanoSpan) |
|
|
|
throws SQLException{ |
|
|
|
throws SQLException { |
|
|
|
this(dataSource, conn, connectNanoSpan, null, null); |
|
|
|
this(dataSource, conn, connectNanoSpan, null, null); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public DruidConnectionHolder(DruidAbstractDataSource dataSource, Connection conn, long connectNanoSpan, |
|
|
|
public DruidConnectionHolder(DruidAbstractDataSource dataSource, Connection conn, long connectNanoSpan, |
|
|
|
Map<String, Object> variables, Map<String, Object> globleVariables) |
|
|
|
Map<String, Object> variables, Map<String, Object> globleVariables) |
|
|
|
throws SQLException{ |
|
|
|
throws SQLException { |
|
|
|
this.dataSource = dataSource; |
|
|
|
this.dataSource = dataSource; |
|
|
|
this.conn = conn; |
|
|
|
this.conn = conn; |
|
|
|
this.createNanoSpan = connectNanoSpan; |
|
|
|
this.createNanoSpan = connectNanoSpan; |
|
|
@ -101,9 +103,7 @@ public final class DruidConnectionHolder { |
|
|
|
|
|
|
|
|
|
|
|
this.connectTimeMillis = System.currentTimeMillis(); |
|
|
|
this.connectTimeMillis = System.currentTimeMillis(); |
|
|
|
this.lastActiveTimeMillis = connectTimeMillis; |
|
|
|
this.lastActiveTimeMillis = connectTimeMillis; |
|
|
|
this.lastExecTimeMillis = connectTimeMillis; |
|
|
|
this.lastExecTimeMillis = connectTimeMillis; |
|
|
|
|
|
|
|
|
|
|
|
this.underlyingAutoCommit = conn.getAutoCommit(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (conn instanceof WrapperProxy) { |
|
|
|
if (conn instanceof WrapperProxy) { |
|
|
|
this.connectionId = ((WrapperProxy) conn).getId(); |
|
|
|
this.connectionId = ((WrapperProxy) conn).getId(); |
|
|
@ -111,46 +111,40 @@ public final class DruidConnectionHolder { |
|
|
|
this.connectionId = dataSource.createConnectionId(); |
|
|
|
this.connectionId = dataSource.createConnectionId(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
boolean initUnderlyHoldability = !holdabilityUnsupported; |
|
|
|
// 下面是一些驱动的默认值,reset时用到
|
|
|
|
DbType dbType = DbType.of(dataSource.dbTypeName); |
|
|
|
|
|
|
|
if (dbType == DbType.sybase //
|
|
|
|
// autoCommit
|
|
|
|
|| dbType == DbType.db2 //
|
|
|
|
this.underlyingAutoCommit = conn.getAutoCommit(); |
|
|
|
|| dbType == DbType.hive //
|
|
|
|
|
|
|
|
|| dbType == DbType.odps //
|
|
|
|
// holdability
|
|
|
|
) { |
|
|
|
DbType dbType = DbType.of(dataSource.dbTypeName); |
|
|
|
initUnderlyHoldability = false; |
|
|
|
boolean initUnderlyingHoldability = !holdabilityUnsupported; |
|
|
|
} |
|
|
|
if (holdabilityUnsupportedDbTypes.contains(dbType)) { |
|
|
|
if (initUnderlyHoldability) { |
|
|
|
initUnderlyingHoldability = false; |
|
|
|
try { |
|
|
|
} |
|
|
|
this.underlyingHoldability = conn.getHoldability(); |
|
|
|
|
|
|
|
} catch (UnsupportedOperationException e) { |
|
|
|
if (initUnderlyingHoldability) { |
|
|
|
holdabilityUnsupported = true; |
|
|
|
try { |
|
|
|
LOG.warn("getHoldability unsupported", e); |
|
|
|
this.underlyingHoldability = conn.getHoldability(); |
|
|
|
} catch (SQLFeatureNotSupportedException e) { |
|
|
|
} catch (Throwable e) { |
|
|
|
holdabilityUnsupported = true; |
|
|
|
holdabilityUnsupported = true; |
|
|
|
LOG.warn("getHoldability unsupported", e); |
|
|
|
LOG.warn("getHoldability error", e); |
|
|
|
} catch (SQLException e) { |
|
|
|
|
|
|
|
// bug fixed for hive jdbc-driver
|
|
|
|
|
|
|
|
if ("Method not supported".equals(e.getMessage())) { |
|
|
|
|
|
|
|
holdabilityUnsupported = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
LOG.warn("getHoldability error", e); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.underlyingReadOnly = conn.isReadOnly(); |
|
|
|
// readOnly
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
this.underlyingReadOnly = conn.isReadOnly(); |
|
|
|
|
|
|
|
} catch (Throwable e) { |
|
|
|
|
|
|
|
LOG.warn("isReadOnly error", e); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// transactionIsolation
|
|
|
|
try { |
|
|
|
try { |
|
|
|
this.underlyingTransactionIsolation = conn.getTransactionIsolation(); |
|
|
|
this.underlyingTransactionIsolation = conn.getTransactionIsolation(); |
|
|
|
} catch (SQLException e) { |
|
|
|
} catch (Throwable e) { |
|
|
|
// compartible for alibaba corba
|
|
|
|
LOG.warn("getTransactionIsolation error", e); |
|
|
|
if ("HY000".equals(e.getSQLState()) |
|
|
|
|
|
|
|
|| "com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException".equals(e.getClass().getName())) { |
|
|
|
|
|
|
|
// skip
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
throw e; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.defaultHoldability = underlyingHoldability; |
|
|
|
this.defaultHoldability = underlyingHoldability; |
|
|
|