Spring 的聲明式事務(wù)是通過(guò)TransactionProxyFactoryBean 來(lái)實(shí)現(xiàn)的,而它是通過(guò)持有一個(gè)攔截器:TransactionInterceptor 來(lái)做到的。
public class TransactionProxyFactoryBean extends ProxyConfig implements FactoryBean, InitializingBean {
private final TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
/**
* Set the transaction manager. This will perform actual
* transaction management: This class is just a way of invoking it.
* @see TransactionInterceptor#setTransactionManager
*/
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionInterceptor.setTransactionManager( transactionManager);
}
。。。。。。。。。。//聲明的事務(wù)屬性在這里得到
//見(jiàn)(DefaultTransactionDefinition)定義
}
//TransactionInterceptor 在service層的方法調(diào)用的時(shí)候,會(huì)更具配置判斷調(diào)用的方法//是否需要事務(wù)的處理,若需要?jiǎng)t獲取設(shè)置事務(wù)屬性對(duì)象和事務(wù)管理器并啟動(dòng)一個(gè)//事務(wù),而其具體的實(shí)現(xiàn)是委托給 TransactionAspectSupport 類(lèi)的//createTransactionIfNecessary 方法實(shí)現(xiàn)的,其類(lèi)結(jié)構(gòu)如下:
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
// Work out the target class: may be null.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface
Class targetClass = (invocation.getThis() != null) ? invocation.getThis().getClass() : null;
// Create transaction if necessary
TransactionInfo txInfo = createTransactionIfNecessary(invocation.getMethod(), targetClass);//此處即是根據(jù)配置的聲明性事務(wù)屬性決定方法事務(wù)級(jí)別
Object retVal = null;
try {
// This is an around advice.
// Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
retVal = invocation.proceed();
}
catch (Throwable ex) {
// target invocation exception
doCloseTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
doFinally(txInfo);
}
doCommitTransactionAfterReturning(txInfo);
return retVal;
}
}
//在TransactionAspectSupport 類(lèi)方法createTransactionIfNecessary()里面根據(jù)配置的聲明性事務(wù)屬性,決定啟動(dòng)一個(gè)事務(wù),和返回事務(wù)級(jí)別(信息):
protected TransactionInfo createTransactionIfNecessary(Method method, Class targetClass) {
// If the transaction attribute is null, the method is non-transactional
TransactionAttribute transAtt = this.transactionAttributeSource.getTransactionAttribute(method, targetClass);
TransactionInfo txInfo = new TransactionInfo(transAtt, method);
if (transAtt != null) {
// We need a transaction for this method
if (logger.isDebugEnabled()) {
logger.debug("Getting transaction for " + txInfo.joinpointIdentification());
}
// The transaction manager will flag an error if an incompatible tx already exists
txInfo.newTransactionStatus(this.transactionManager.getTransaction(transAtt));
//此處的參數(shù) this.transactionManager.getTransaction(transAtt) 即是調(diào)用各具體平臺(tái)的 transactionManager 來(lái)獲取她的事務(wù)屬性,在獲取事務(wù)屬性的同時(shí)她會(huì)更具具體的事務(wù)屬性 來(lái)決定是否開(kāi)始和怎么開(kāi)始一個(gè)事務(wù);見(jiàn)類(lèi)AbstractPlatformTransactionManager 結(jié)構(gòu)。
public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {
。。。。。。。。。。。。。。。。。。。。。
public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
if (isExistingTransaction(transaction)) {
//下面即是 更具具體的配置事務(wù)屬性 來(lái)決定事務(wù)
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
throw new IllegalTransactionStateException(
"Transaction propagation 'never' but existing transaction found");
}
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
if (debugEnabled) {
logger.debug("Suspending current transaction");
}
Object suspendedResources = suspend(transaction);
boolean newSynchronization = (this.transactionSynchronization == SYNCHRONIZATION_ALWAYS);
return newTransactionStatus(
null, false, newSynchronization, definition.isReadOnly(), debugEnabled, suspendedResources);
}
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
if (debugEnabled) {
logger.debug("Creating new transaction, suspending current one");
}
Object suspendedResources = suspend(transaction);
//此處的doBegin 方法給更具具體的平臺(tái)和配置事務(wù)屬性來(lái)啟動(dòng)一個(gè)事務(wù)
doBegin(transaction, definition);
boolean newSynchronization = (this.transactionSynchronization != SYNCHRONIZATION_NEVER);
return newTransactionStatus(
transaction, true, newSynchronization, definition.isReadOnly(), debugEnabled, suspendedResources);
}
。。。。。。。。。。。。。。。。。。。。。
}
// We always bind the TransactionInfo to the thread, even if
// we didn't create a new transaction here.
// This guarantees that the TransactionInfo stack will be
// managed correctly even if no transaction was created by
// this aspect.
txInfo.bindToThread();
return txInfo;
}
//下面是事務(wù)的提交操作,回滾類(lèi)似
protected void doCommitTransactionAfterReturning(TransactionInfo txInfo) {
if (txInfo != null && txInfo.hasTransaction()) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking commit for transaction on " + txInfo.joinpointIdentification());
}
//這里的transactionManager 就是Spring配置文件里面配置的事務(wù) 如:org.springframework.orm.hibernate3.HibernateTransactionManager 。
this.transactionManager.commit(txInfo.getTransactionStatus());
}
}
//
protected void doFinally(TransactionInfo txInfo) {
if (txInfo != null) {
txInfo.restoreThreadLocalStatus();
}
}
private void restoreThreadLocalStatus() {
// Use stack to restore old transaction TransactionInfo.
// Will be null if none was set.
currentTransactionInfo.set(oldTransactionInfo);
}
//下面以 HibernateTransactionManager 例,說(shuō)說(shuō)事務(wù)的開(kāi)始和提交/回滾
//此dobegin()方法即是開(kāi)始一個(gè)事務(wù)
protected void doBegin(Object transaction, TransactionDefinition definition) {
HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;
if (txObject.getSessionHolder() == null) {
Session session = SessionFactoryUtils.getSession(
getSessionFactory(), getEntityInterceptor(), getJdbcExceptionTranslator(), false);
if (logger.isDebugEnabled()) {
logger.debug("Opened new session [" + session + "] for Hibernate transaction");
}
txObject.setSessionHolder(new SessionHolder(session), true);
}
txObject.getSessionHolder().setSynchronizedWithTransaction(true);
Session session = txObject.getSessionHolder().getSession();
try {
Connection con = session.connection();
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
if (definition.isReadOnly() && txObject.isNewSessionHolder()) {
// just set to NEVER in case of a new Session for this transaction
session.setFlushMode(FlushMode.NEVER);
}
if (!definition.isReadOnly() && !txObject.isNewSessionHolder()) {
// we need AUTO or COMMIT for a non-read-only transaction
FlushMode flushMode = session.getFlushMode();
if (FlushMode.NEVER.equals(flushMode)) {
session.setFlushMode(FlushMode.AUTO);
txObject.getSessionHolder().setPreviousFlushMode(flushMode);
}
}
// add the Hibernate transaction to the session holder
//此處即是真正的調(diào)用了hibernate的session開(kāi)始一個(gè)事務(wù)session.beginTransaction() 。
txObject.getSessionHolder().setTransaction(session.beginTransaction());
// register transaction timeout
if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) {
txObject.getSessionHolder().setTimeoutInSeconds(definition.getTimeout());
}
// register the Hibernate Session's JDBC Connection for the DataSource, if set
if (getDataSource() != null) {
ConnectionHolder conHolder = new ConnectionHolder(con);
if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) {
conHolder.setTimeoutInSeconds(definition.getTimeout());
}
if (logger.isDebugEnabled()) {
logger.debug("Exposing Hibernate transaction as JDBC transaction [" +
conHolder.getConnection() + "]");
}
TransactionSynchronizationManager.bindResource(getDataSource(), conHolder);
txObject.setConnectionHolder(conHolder);
}
// bind the session holder to the thread
if (txObject.isNewSessionHolder()) {
TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder());
}
}
catch (Exception ex) {
SessionFactoryUtils.closeSessionIfNecessary(session, getSessionFactory());
throw new CannotCreateTransactionException("Could not create Hibernate transaction", ex);
}
}
//回滾
protected void doCommit(DefaultTransactionStatus status) {
HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction();
。。。。。。。。。。。。。。。。。。。。。。。。。。
try {
txObject.getSessionHolder().getTransaction().commit();
}
catch (net.sf.hibernate.TransactionException ex) {
// assumably from commit call to the underlying JDBC connection
throw new TransactionSystemException("Could not commit Hibernate transaction", ex);
}
catch (JDBCException ex) {
// assumably failed to flush changes to database
throw convertJdbcAccessException(ex.getSQLException());
}
catch (HibernateException ex) {
// assumably failed to flush changes to database
throw convertHibernateAccessException(ex);
}
}
else {
// The TransactionInfo.hasTransaction() method will return
// false. We created it only to preserve the integrity of
// the ThreadLocal stack maintained in this class.
if (logger.isDebugEnabled())
logger.debug("Don't need to create transaction for " + methodIdentification(method) +
": this method isn't transactional");
}