JDBCContext

dylanduk發表於2013-03-29
成員變數

owner:session
connectionManager:管理連線
isTransactionCallbackRegistered:是否註冊回撥
hibernateTransaction:JTATransaction或CMTTransaction事例

重要方法

borrowConnection由session.connection呼叫
public Connection borrowConnection() {
return connectionManager.borrowConnection();
}

connection由JDBCTransaction在事務開始或完成時呼叫
public Connection connection() throws HibernateException {
if ( owner.isClosed() ) {
throw new SessionException( "Session is closed" );
}

return connectionManager.getConnection();
}

registerCallbackIfNecessary和registerSynchronizationIfPossible 註冊同步
JDBCTransaction: 本地同步
JTATransaction:尋找javax.trasaction.TransactionManager和啟用著的JTA事務,如果滿足註冊JTA同步,否則呼叫registerCallbackIfNecessary以支援本地同步
CMTTransaction:尋找javax.trasaction.TransactionManager和啟用著的JTA事務
,如果不滿足則拋錯即CMT不支援本地同步
public boolean registerCallbackIfNecessary() {
if ( isTransactionCallbackRegistered ) {
return false;
}
else {
isTransactionCallbackRegistered = true;
return true;
}

}
public boolean registerSynchronizationIfPossible() {
if ( isTransactionCallbackRegistered ) {
// we already have a callback registered; either a local
// (org.hibernate.Transaction) transaction has accepted
// callback responsibilities, or we have previously
// registered a transaction synch.
return true;
}
boolean localCallbacksOnly = owner.getFactory().getSettings()
.getTransactionFactory()
.areCallbacksLocalToHibernateTransactions();
if ( localCallbacksOnly ) {
// the configured transaction-factory says it only supports
// local callback mode, so no sense attempting to register a
// JTA Synchronization
return false;
}
TransactionManager tm = owner.getFactory().getTransactionManager();
if ( tm == null ) {
// if there is no TM configured, we will not be able to access
// the javax.transaction.Transaction object in order to
// register a synch anyway.
return false;
}
else {
try {
if ( !isTransactionInProgress() ) {
log.trace( "TransactionFactory reported no active transaction; Synchronization not registered" );
return false;
}
else {
javax.transaction.Transaction tx = tm.getTransaction();
if ( JTAHelper.isMarkedForRollback( tx ) ) {
// transactions marked for rollback-only cause some TM impls to throw exceptions
log.debug( "Transaction is marked for rollback; skipping Synchronization registration" );
return false;
}
else {
if ( hibernateTransaction == null ) {
hibernateTransaction = owner.getFactory().getSettings().getTransactionFactory().createTransaction( this, owner );
}
tx.registerSynchronization( new CacheSynchronization(owner, this, tx, hibernateTransaction) );
isTransactionCallbackRegistered = true;
log.debug("successfully registered Synchronization");
return true;
}
}
}
catch( HibernateException e ) {
throw e;
}
catch (Exception e) {
throw new TransactionException( "could not register synchronization with JTA TransactionManager", e );
}
}
}

判斷事務是否啟用狀態
public boolean isTransactionInProgress() {
return owner.getFactory().getSettings().getTransactionFactory()
.isTransactionInProgress( this, owner, hibernateTransaction );
}

只要本地同步或JTA同步執行已註冊,在事務完成之後
如果沒有註冊,則session.close、session.disconnect進行資源清理時呼叫
public void afterTransactionCompletion(boolean success, Transaction tx) {
log.trace( "after transaction completion" );

if ( getFactory().getStatistics().isStatisticsEnabled() ) {
getFactory().getStatisticsImplementor().endTransaction(success);
}

connectionManager.afterTransaction();

isTransactionCallbackRegistered = false;
hibernateTransaction = null;
owner.afterTransactionCompletion(success, tx);
}

afterNontransactionalQuery(名字取得不好)非事務操作:在每條語句執行後判斷isTransactionInProgress==false時執行
/**
* Called after executing a query outside the scope of
* a Hibernate or JTA transaction
*/
public void afterNontransactionalQuery(boolean success) {
log.trace( "after autocommit" );
try {
// check to see if the connection is in auto-commit
// mode (no connection means aggressive connection
// release outside a JTA transaction context, so MUST
// be autocommit mode)
boolean isAutocommit = connectionManager.isAutoCommit();

connectionManager.afterTransaction();

if ( isAutocommit ) {
owner.afterTransactionCompletion(success, null);
}
}
catch (SQLException sqle) {
throw JDBCExceptionHelper.convert(
owner.getFactory().getSQLExceptionConverter(),
sqle,
"could not inspect JDBC autocommit mode"
);
}
}