事務的傳播機制定義在TransactionDefinition介面中,我們也可以通過枚舉類Propagation類調用,下面我也附上兩個類的源碼供參考。 REQUIRED(預設):支援使用當前事務,如果當前事務不存在,建立一個新事務。 SUPPORTS:支援使用當前事務,如果當前事務不存在,則不使用事務。 MANDATORY:中文翻譯為強制,支援使用當前事務,如果當前事務不存在,則拋出Exception。 REQUIRES_NEW:建立一個新事務,如果當前事務不存在,把當前事務掛起。 NOT_SUPPORTED:無事務執行,如果當前事務不存在,把當前事務掛起。 NEVER:無事務執行,如果當前有事務則拋出Exception。 NESTED:嵌套事務,如果當前事務存在,那麼在嵌套的事務中執行。如果當前事務不存在,則表現跟REQUIRED一樣。
重點講一下requires_new和nested的區別,requires_new完全是一個新事務,nested是一個外部事務的子事務,是外部事務的一部分,如果嵌套事務發生異常復原,則只復原嵌套事務部分。而外部事務的提交和復原均會提交/復原嵌套事務。requires這是兩個事務互不干擾,如果內部事務發生異常且異常拋到了外部調用方法,那麼兩個事務都復原,如果內部事務提交成功,外部事務提交失敗,外部事務不影響內部事務,或者外部事務提交成功,但內部事務失敗的異常被外部事務catch住,則不影響外部事務。
package org.springframework.transaction.annotation;import org.springframework.transaction.TransactionDefinition;public enum Propagation { /** * Support a current transaction, create a new one if none exists. * Analogous to EJB transaction attribute of the same name. * <p>This is the default setting of a transaction annotation. */ REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED), /** * Support a current transaction, execute non-transactionally if none exists. * Analogous to EJB transaction attribute of the same name. * <p>Note: For transaction managers with transaction synchronization, * PROPAGATION_SUPPORTS is slightly different from no transaction at all, * as it defines a transaction scope that synchronization will apply for. * As a consequence, the same resources (JDBC Connection, Hibernate Session, etc) * will be shared for the entire specified scope. Note that this depends on * the actual synchronization configuration of the transaction manager. * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setTransactionSynchronization */ SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS), /** * Support a current transaction, throw an exception if none exists. * Analogous to EJB transaction attribute of the same name. */ MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY), /** * Create a new transaction, suspend the current transaction if one exists. * Analogous to EJB transaction attribute of the same name. * <p>Note: Actual transaction suspension will not work on out-of-the-box * on all transaction managers. This in particular applies to JtaTransactionManager, * which requires the {@code javax.transaction.TransactionManager} to be * made available it to it (which is server-specific in standard J2EE). * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager */ REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW), /** * Execute non-transactionally, suspend the current transaction if one exists. * Analogous to EJB transaction attribute of the same name. * <p>Note: Actual transaction suspension will not work on out-of-the-box * on all transaction managers. This in particular applies to JtaTransactionManager, * which requires the {@code javax.transaction.TransactionManager} to be * made available it to it (which is server-specific in standard J2EE). * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager */ NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED), /** * Execute non-transactionally, throw an exception if a transaction exists. * Analogous to EJB transaction attribute of the same name. */ NEVER(TransactionDefinition.PROPAGATION_NEVER), /** * Execute within a nested transaction if a current transaction exists, * behave like PROPAGATION_REQUIRED else. There is no analogous feature in EJB. * <p>Note: Actual creation of a nested transaction will only work on specific * transaction managers. Out of the box, this only applies to the JDBC * DataSourceTransactionManager when working on a JDBC 3.0 driver. * Some JTA providers might support nested transactions as well. * @see org.springframework.jdbc.datasource.DataSourceTransactionManager */ NESTED(TransactionDefinition.PROPAGATION_NESTED); private final int value; Propagation(int value) { this.value = value; } public int value() { return this.value; }}
package org.springframework.transaction;import java.sql.Connection;public interface TransactionDefinition { int PROPAGATION_REQUIRED = 0; int PROPAGATION_SUPPORTS = 1; int PROPAGATION_MANDATORY = 2; int PROPAGATION_REQUIRES_NEW = 3; int PROPAGATION_NOT_SUPPORTED = 4; int PROPAGATION_NEVER = 5; int PROPAGATION_NESTED = 6; int ISOLATION_DEFAULT = -1; int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED; int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED; int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ; int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE; int TIMEOUT_DEFAULT = -1; //事務的傳播行為 int getPropagationBehavior(); //事務的隔離等級 int getIsolationLevel(); //事務的到期時間 int getTimeout(); //事務的讀寫特性 boolean isReadOnly(); //事務名 String getName();}