實(shí)際上,在spring的事務(wù)中,只要該類被設(shè)置為了事務(wù)代理:
?
攔截器都會(huì)創(chuàng)建一個(gè)TransactionInfo 對(duì)象:
?
TransactionInfo txInfo = new TransactionInfo(txAttr, method);
?
?
而且如果
只要被調(diào)用的方法設(shè)置了事務(wù)屬性(txAttr),不管是什么屬性都會(huì)調(diào)用:
?
txInfo.newTransactionStatus(this.transactionManager.getTransaction(txAttr));
?
根據(jù)該方法的事務(wù)屬性(definition )的不同,this.transactionManager.getTransaction(txAttr)的返回值會(huì)有所不同(代碼見(jiàn)AbstractPlatformTransactionManager),具體為以下幾種情況:
1.當(dāng)前沒(méi)有事務(wù)時(shí)(即以下代碼中的((HibernateTransactionObject) transaction).hasTransaction()返回false),會(huì)返回以下幾種:
?
// 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.當(dāng)前有事務(wù)時(shí)
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被綁定到當(dāng)前線程上作為當(dāng)前事務(wù):
?
txInfo.bindToThread()
?
然后,調(diào)用實(shí)際的目標(biāo)類的方法并捕捉異常:
?
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;
?}
?
?
另外一點(diǎn),TransactionInfo的newTransactionStatus調(diào)用時(shí)如果參數(shù)的不是null,TransactionInfo.hasTransaction()方法返回true;
?
重要提示:
在spring中創(chuàng)建的事務(wù)代理類并是目標(biāo)類的超類,只是一個(gè)實(shí)現(xiàn)這目標(biāo)類接口的類,該類會(huì)調(diào)用目標(biāo)類的方法,所在如果一個(gè)目標(biāo)類中的方法調(diào)用自身的另一個(gè)事務(wù)方法,另一個(gè)方法只是作為普通方法來(lái)調(diào)用,并不會(huì)加入事務(wù)機(jī)制
參考資料:
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 的源代碼