1. 程式人生 > >Spring事務的傳播特性和隔離級別(持續更新中)

Spring事務的傳播特性和隔離級別(持續更新中)

Spring TransactionDefinition介面中定義了事務的隔離級別和事務的傳播特性

傳播特性

例子:

class ClassA{
        method(){
            //邏輯處理1
            classB.methodB();
            //邏輯處理2
        }
    }
 class ClassB{
 		//邏輯處理3
        method();
        //邏輯處理4
    }

1. PROPAGATION_REQUIRED

/**
    * Support a current transaction; create a new one if none exists.
    * Analogous to the EJB transaction attribute of the same name.
    * <p>This is typically the default setting of a transaction definition,
    * and typically defines a transaction synchronization scope.
    */
int PROPAGATION_REQUIRED = 0;

如果事務不存在則建立,如果存在使用存在的事務

例如:

class ClassA{
	    @Transactional(propagation = Propagation.REQUIRED)
        method(){
            //邏輯處理1
            classB.methodB();
            //邏輯處理2
        }
    }
 class ClassB{
 		//邏輯處理3
 		@Transactional(propagation = Propagation.REQUIRED)
method(); //邏輯處理4 }

classA.method()建立PROPAGATION_REQUIRED 事務後,classB.mehtod()會使用classA.method()建立的事務,不會建立新的事務。如果邏輯處理2失敗丟擲異常則classB.mehtod()方法會被回滾。當classA.method()沒有打上PROPAGATION_REQUIRED 標誌,那麼如果classB.mehtod()回滾後,classA.method()邏輯處理1的內容不會被回滾。

2. PROPAGATION_SUPPORTS

/**
 * Support a current transaction; execute non-transactionally if none exists.
 * */
int PROPAGATION_SUPPORTS = 1;

如果當前存在事務,則使用存在的事務,如果不存在則使用非事務方式處理。

例如:

class ClassA{
	    @Transactional(propagation = Propagation.REQUIRED)
        method(){
            //邏輯處理1
            classB.methodB();
            //邏輯處理2
        }
    }
 class ClassB{
 		//邏輯處理3
 		@Transactional(propagation = Propagation.SUPPORTS)
        method();
        //邏輯處理4
    }

classA.method()建立PROPAGATION_REQUIRED 事務後,classB.mehtod()會使用classA.method()建立的事務.如果classA.method()沒使用PROPAGATION_REQUIRED建立事務,則classB.mehtod()會以非事務方式執行。

3. PROPAGATION_MANDATORY

/**
	 * Support a current transaction; throw an exception if no current transaction
	 * exists. Analogous to the EJB transaction attribute of the same name.
	 * <p>Note that transaction synchronization within a {@code PROPAGATION_MANDATORY}
	 * scope will always be driven by the surrounding transaction.
	 */
	int PROPAGATION_MANDATORY = 2;

如果當前存在事務,則使用存在的事務,如果不存在則丟擲異常。 例如:

class ClassA{
	    @Transactional(propagation = Propagation.REQUIRED)
        method(){
            //邏輯處理1
            classB.methodB();
            //邏輯處理2
        }
    }
 class ClassB{
 		//邏輯處理3
 		@Transactional(propagation = Propagation.MANDATORY)
        method();
        //邏輯處理4
    }

classA.method()建立PROPAGATION_REQUIRED 事務後,classB.mehtod()會使用classA.method()建立的事務.如果classA.method()沒使用PROPAGATION_REQUIRED建立事務,則classB.mehtod()會以非事務方式執行。則classB.mehtod()會丟擲異常。

4. PROPAGATION_REQUIRES_NEW

/**
	 * Create a new transaction, suspending the current transaction if one exists.
	 * Analogous to the EJB transaction attribute of the same name.
	 * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box
	 * on all transaction managers. This in particular applies to
	 * {@link org.springframework.transaction.jta.JtaTransactionManager},
	 * which requires the {@code javax.transaction.TransactionManager} to be
	 * made available it to it (which is server-specific in standard Java EE).
	 * <p>A {@code PROPAGATION_REQUIRES_NEW} scope always defines its own
	 * transaction synchronizations. Existing synchronizations will be suspended
	 * and resumed appropriately.
	 * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
	 */
	int PROPAGATION_REQUIRES_NEW = 3;

永遠建立新的事務,如果當前存在事務則掛起 例如:

class ClassA{
	    @Transactional(propagation = Propagation.REQUIRED)
        method(){
            //邏輯處理1
            classB.methodB();
            //邏輯處理2
        }
    }
 class ClassB{
 		//邏輯處理3
 		@Transactional(propagation = Propagation.REQUIRES_NEW)
        method();
        //邏輯處理4
    }

當classB.method()打上PROPAGATION_REQUIRES_NEW的事務標誌,執行classA.method()方法,當執行到classB.method()的時候,會檢查上下文有沒有事務,如果classA.method()有事務,則會掛起calssA.method()的事務,新建一個屬於classB.method()的事務,當classB.method()的事務執行結束的時候,則會喚醒classA.method()的事務。PROPAGATION_REQUIRES_NEW和PROPAGATION_REQUIRED的差別在於回滾,當classB.method()的事務提交後,classA.method()執行失敗,只會回滾classA.method不會回滾classB.method(),當classB.method()執行失敗,異常被classA.methodA()方法 catch到的話,classA.method()事務不會回滾。

5. PROPAGATION_NOT_SUPPORTED

/**
	 * Do not support a current transaction; rather always execute non-transactionally.
	 * Analogous to the EJB transaction attribute of the same name.
	 * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box
	 * on all transaction managers. This in particular applies to
	 * {@link org.springframework.transaction.jta.JtaTransactionManager},
	 * which requires the {@code javax.transaction.TransactionManager} to be
	 * made available it to it (which is server-specific in standard Java EE).
	 * <p>Note that transaction synchronization is <i>not</i> available within a
	 * {@code PROPAGATION_NOT_SUPPORTED} scope. Existing synchronizations
	 * will be suspended and resumed appropriately.
	 * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
	 */
	int PROPAGATION_NOT_SUPPORTED = 4;

永遠使用非事務方式執行,如果當前存在事務則掛起 例如:

class ClassA{
	    @Transactional(propagation = Propagation.REQUIRED)
        method(){
            //邏輯處理1
            classB.methodB();
            //邏輯處理2
        }
    }
 class ClassB{
 		//邏輯處理3
 		@Transactional(propagation = Propagation.NOT_SUPPORTED)
        method();
        //邏輯處理4
    }

當執行到classB.method()方法的時候,檢查上下文中存在事務,則掛起classA的事務執行,classB.method()方法執行完成後,喚醒classA.method()的事務。

6. PROPAGATION_NEVER

/**
    * Do not support a current transaction; throw an exception if a current transaction
    * exists. Analogous to the EJB transaction attribute of the same name.
    * <p>Note that transaction synchronization is <i>not</i> available within a
    * {@code PROPAGATION_NEVER} scope.
    */
   int PROPAGATION_NEVER = 5;

不支援事務執行方式,如果存在事務則丟擲異常 例如:

class ClassA{
	    @Transactional(propagation = Propagation.REQUIRED)
        method(){
            //邏輯處理1
            classB.methodB();
            //邏輯處理2
        }
    }
 class ClassB{
 		//邏輯處理3
 		@Transactional(propagation = Propagation.NEVER)
        method();
        //邏輯處理4
    }

classA.method() 打上了PROPAGATION_REQUIRED標誌,建立了事務,當執行到classB.method()方法時,檢查到存在活動的事務,則丟擲異常。

7. PROPAGATION_NESTED

	/**
	 * Execute within a nested transaction if a current transaction exists,
	 * behave like {@link #PROPAGATION_REQUIRED} otherwise. There is no
	 * analogous feature in EJB.
	 * <p><b>NOTE:</b> Actual creation of a nested transaction will only work on
	 * specific transaction managers. Out of the box, this only applies to the JDBC
	 * {@link org.springframework.jdbc.datasource.DataSourceTransactionManager}
	 * when working on a JDBC 3.0 driver. Some JTA providers might support
	 * nested transactions as well.
	 * @see org.springframework.jdbc.datasource.DataSourceTransactionManager
	 */
	int PROPAGATION_NESTED = 6;

如果存在一個活動的事務,則執行在一個巢狀的事務中. 如果沒有活動事務, 安按照PROPAGATION_REQUIRED 事務屬性執行 例如:

class ClassA{
	    @Transactional(propagation = Propagation.REQUIRED)
        method(){
            //邏輯處理1
            classB.methodB();
            //邏輯處理2
        }
    }
 class ClassB{
 		//邏輯處理3
 		@Transactional(propagation = Propagation.NESTED)
        method();
        //邏輯處理4
    }

當classB.method()打上PROPAGATION_NOT_SUPPORTED的事務標誌後,開始執行classA.method()方法,當執行到classB.method()的時候,此時classA.method()方法有事務,會用當前事務,如果 classB.method()執行失敗,只會回滾 classB.method(),不會回滾classA.method()。只有當classA.method()執行完成後才會提交classB.method()的事務,如果classA.method()方法沒有事務,classB.method()就會新建一個事務,類似打PROPAGATION_REQUIRED標誌的事務。

隔離級別