1。XAPool是如何wrap jdbc driver返回的PreparedStatement的。
以下是StandardConnectionHandler中的checkPreparedCache代码片断
synchronized PreparedStatement checkPreparedCache(
String sql,
int type,
int concurrency)
throws SQLException {
log.debug(
"StandardConnectionHandle:checkPreparedCache sql='" + sql + "'");
PreparedStatement ret = null; // the return value
// NOTE - We include the Connection in the lookup key. This has no
// effect here but is needed by StandardXAConnection where the the physical
// Connection used can vary over time depending on the global transaction.
String lookupKey = sql + type + concurrency;
// used to lookup statements
if (preparedStatementCache != null) {
Object obj = preparedStatementCache.get(lookupKey);
// see if there's a PreparedStatement already
if (obj != null) { // if there is
ret = (PreparedStatement) obj; // use as return value
try {
ret.clearParameters(); // make it look like new
} catch (SQLException e) {
// Bad statement, so we have to create a new one
ret = createPreparedStatement(sql, type, concurrency);
}
preparedStatementCache.remove(lookupKey);
// make sure it cannot be re-used
inUse.put(lookupKey, ret);
// make sure it gets reused by later delegates
} else { // no PreparedStatement ready
ret = createPreparedStatement(sql, type, concurrency);
inUse.put(lookupKey, ret);
// will get saved in prepared statement cache
}
} else {
ret = createPreparedStatement(sql, type, concurrency);
}
// We don't actually give the application a real PreparedStatement. Instead
// they get a StandardPreparedStatement that delegates everything except
// PreparedStatement.close();
ret = new StandardPreparedStatement(this, ret, lookupKey);
return ret;
}
2。StandardPreparedStatement的Close方法代码片断
public void close() throws SQLException {
// Note no check for already closed - some servers make mistakes
closed = true;
if (con.preparedStmtCacheSize == 0) {
// no cache, so we just close
if (ps != null) {
ps.close();
}
} else {
con.returnToCache(key);
// return the underlying statement to the cache
}
}
3。xapool StandardPoolDataSource的getConnection 原理:
StandardPoolDataSource.getConnection --> GenericPool.checkOut-->StandardPoolDataSource.create -->StandardPoolDataSource.getPooledConnection:返回StandardPooledConnection。
StandardPooledConnection通过StandardDataSource.getConnection获取jdbc driver返回的connection(physical connection),然后通过工厂方法newConnectionHandle采用StandardConnectionHandler对该connection进行包装。StandardConnectionHandler对PreparedStatement进行重新包装和Cache,对connection.close进行了控制。
4。xapool StandardXAPoolDataSource的getConnection的原理:
StandardXAPoolDataSource.getConnection -->StandardPoolDataSource.getConnection-->StandardXAPoolDataSource.create -->XADataSource.getXAConnection -->StandardXADatasource.getXAConnection:返回StandardXAConnection。
StandardXAConnection通过StandardDataSource.getConnection获取jdbc driver返回的connection(physical connection),然后通过工厂方法newConnectionHandle采用StandardXAConnectionHandle对该connection进行包装。StandardXAConnectionHandler继承自StandardConnectionHandler。
5。xapool从StandardPoolDataSource获取的 Connection的关闭原理。
StandardPooledConnection.close-->StandardConnectionHandler.close(设置closed=true,回收PreparedStatement)-->StandardPooledConnection.closeEvent-->StandardPoolDataSource.connectionClosed-->GenericPool.checkIn(返回连接池)
6.xapool中对连接池进行管理的类是GenericPool,该类的checkOut和checkIn方法分别完成连接获取和连接回收功能。checkOut从unlocked池中获取可用的连接,如果需要进行检查或者测试,然后返回;如果发现unlocked池中没有连接,在连接数小于maxSize的时候调用PoolHelper的实现类创建连接,如果连接数已经达到或者超过maxSize,调用wait使当前进程进入等待状态(等待期限和等待间隔可以设置),如果等待过程中其他线程释放了connection返回可用的connection,否则异常:GenericPool:checkOut ERROR impossible to obtain a new object from the pool