實際上,在spring的事務中,只要該類被設置為了事務代理:
?
攔截器都會創建一個TransactionInfo 對象:
?
TransactionInfo txInfo = new TransactionInfo(txAttr, method);
?
?
而且如果 只要被調用的方法設置了事務屬性(txAttr),不管是什么屬性都會調用:
?
txInfo.newTransactionStatus(this.transactionManager.getTransaction(txAttr));
?
根據該方法的事務屬性(definition )的不同,this.transactionManager.getTransaction(txAttr)的返回值會有所不同(代碼見AbstractPlatformTransactionManager),具體為以下幾種情況:
1.當前沒有事務時(即以下代碼中的((HibernateTransactionObject) transaction).hasTransaction()返回false),會返回以下幾種:
?
// Check definition settings for new transaction.
??if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
???throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
??}
?
??// No existing transaction found -> check propagation behavior to find out how to behave.
??if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
???throw new IllegalTransactionStateException(
?????"Transaction propagation 'mandatory' but no existing transaction found");
??}
??else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
????definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
????? definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
???if (debugEnabled) {
????logger.debug("Creating new transaction with name [" + definition.getName() + "]");
???}
???doBegin(transaction, definition);
???boolean newSynchronization = (this.transactionSynchronization != SYNCHRONIZATION_NEVER);
???return newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null);
??}
??else {
???// Create "empty" transaction: no actual transaction, but potentially synchronization.
???boolean newSynchronization = (this.transactionSynchronization == SYNCHRONIZATION_ALWAYS);
???return newTransactionStatus(definition, null, false, newSynchronization, debugEnabled, null);
??}
?
2.當前有事務時
private TransactionStatus handleExistingTransaction(
???TransactionDefinition definition, Object transaction, boolean debugEnabled)
???throws TransactionException {
?
??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(
?????definition, null, false, newSynchronization, debugEnabled, suspendedResources);
??}
?
??if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
???if (debugEnabled) {
????logger.debug("Suspending current transaction, creating new transaction with name [" +
??????definition.getName() + "]");
???}
???Object suspendedResources = suspend(transaction);
???doBegin(transaction, definition);
???boolean newSynchronization = (this.transactionSynchronization != SYNCHRONIZATION_NEVER);
???return newTransactionStatus(
?????definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
??}
?
??if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
???if (!isNestedTransactionAllowed()) {
????throw new NestedTransactionNotSupportedException(
??????"Transaction manager does not allow nested transactions by default - " +
??????"specify 'nestedTransactionAllowed' property with value 'true'");
???}
???if (debugEnabled) {
????logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
???}
???if (useSavepointForNestedTransaction()) {
????// Create savepoint within existing Spring-managed transaction,
????// through the SavepointManager API implemented by TransactionStatus.
????// Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
????DefaultTransactionStatus status =
??????newTransactionStatus(definition, transaction, false, false, debugEnabled, null);
????status.createAndHoldSavepoint();
????return status;
???}
???else {
????// Nested transaction through nested begin and commit/rollback calls.
????// Usually only for JTA: Spring synchronization might get activated here
????// in case of a pre-existing JTA transaction.
????doBegin(transaction, definition);
????boolean newSynchronization = (this.transactionSynchronization != SYNCHRONIZATION_NEVER);
????return newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null);
???}
??}
?
最后,txInfo被綁定到當前線程上作為當前事務:
?
txInfo.bindToThread()
?
然后,調用實際的目標類的方法并捕捉異常:
?
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;
?}
?
?
另外一點,TransactionInfo的newTransactionStatus調用時如果參數的不是null,TransactionInfo.hasTransaction()方法返回true;
?
重要提示:
在spring中創建的事務代理類并是目標類的超類,只是一個實現這目標類接口的類,該類會調用目標類的方法,所在如果一個目標類中的方法調用自身的另一個事務方法,另一個方法只是作為普通方法來調用,并不會加入事務機制

參考資料:
1.Spring Reference Manual:http://static.springframework.org/spring/docs/1.2.x/reference/index.html
2.Spring API doc:http://static.springframework.org/spring/docs/1.2.x/api/index.html
3.Spring 的源代碼