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