1. 程式人生 > >Spring原始碼分析之事務

Spring原始碼分析之事務

Spring提供一流的事務管理,分為宣告式事務和程式設計式事務。

1 Spring的事務

事務是一組任務組成的工作單元,執行的結果是要麼全部執行,要麼都不執行。

Spring事務的優點:

 提供統一的程式設計模式  提供更簡單,更易用的事務管理   支援宣告事務    整合Spring對資料訪問的抽象

2 事務的ACID特性

原子性:

要麼事務的中的任務全部執行,要不都不執行

一致性:事務必須保證和資料庫的一致性,即資料庫的資料必須和現實的資料一致。

隔離性

不同的事務之間互不干擾

永續性:

如果事務執行成功,無論系統發生什麼情況,事務的執行結果都是永久的

3 事務的缺陷

髒讀取:

一個事務讀取另一個事務尚未提交的更新

不可重複的讀取:

一個事務前後兩次讀取資料都不一致,因為前後讀取期間有另一個事務改變了資料。不可重複讀讀到的是更改或者是刪除的資料

幻讀:

A事務讀取了B事務提交的新增資料,這時候A事務就會出現幻象讀的問題,幻象讀讀到的是新增的資料

4 資料庫鎖的機制

根據鎖定的物件不同,可以分為表鎖定和行鎖定,前者對整個表鎖定,或者對錶中的特定的行鎖定。從併發事務鎖定的關係上看,可以分為共享鎖定和獨佔鎖定。

行共享鎖定:一般可以通過select for update來隱式來獲取,也可以通過lock table in row share mode.行共享鎖並不防止對資料行進行更改的操作,但是可以防止其它會話獲取獨佔性資料表鎖定。

行獨佔鎖定:可以通過insert update delete來語句隱式來獲取,可以通過lock table in row exclusive mode.這個鎖定可以防止其它會話獲取一個共享鎖定,共享行獨佔鎖定或獨佔鎖定。

表共享鎖定:lock table in share mode

表共享行獨佔:lock table in share mode row exclusive mode.

表獨佔:lock table in Exclusive mode,防止其它會話的所有的鎖。

5 事務隔離級別

READ UNCOMMITED  READ COMMITED  REPEATABLE READ  SERIALIZABLE

6 事務管理關鍵抽象

在事務管理管理SPI高層抽象層主要包括3個介面,分別是TransactionDefinition<------------PlaformTransactionManager------>TransactionStatus

TransactionDefinition用於標書事務的隔離級別,超時時間,是否為只讀事務和事務傳播等控制事務具體行為的事務屬性,這些事務屬性可以通過XML配置或註解描述提供,也可以通過手工程式設計的方式設定。

PlatformTransactionManager根據TransactionDefinition提供的事務屬性配置資訊,建立事務,並用TransactionStatus描述這個啟用事務的狀態。

TransactionDefinition:

TransactionDefinition定義了Spring相容性的事務屬性,這些屬性對事務管理控制的若干方面進行配置。

事務隔離:當前事務和其它事務的隔離的程度。在TranscationDefiniton介面中,定義了和java.sql.Connnection介面彙總同名的4個隔離級別:

ISOLATION_READ_UNCOMMITED,ISOLATION_READ_COMMITTED,ISOLATION_REPEATABLE_READ,ISOLATION_SERIALIZABLE,還有一個預設的

隔離級別:ISOLATION_DEFUALT

事務傳播:通常一個事務中執行的所有程式碼都會執行在同一事務上下文中,但是Spring也提供了幾個可選的事務傳播型別,如掛起當前的事務,建立一個新的

事務。

事務超時:

事務在超時前能執行多久,超過時間後,事務會被回滾。

只讀狀態:

只讀事務不修改任何資料,效能高。

TransactionStatus:

TransactionStatus代表一個事務的具體執行狀態,事務管理器可以通過該介面來獲取事務執行時期的狀態資訊,可以通過該介面間接地回滾事務。該介面繼承於SavepointManager.

SavepintManager介面擁有一下的方法:

Object createSavepoint()

建立一個儲存點物件,以便後面可以利用rollbackToSavePoint(Object savepoint)方法回滾大特定的儲存點上

void rollbackToSavepoint(Object savepoint)

將事務回滾到特定的儲存點上,被回滾的儲存單將自動釋放。

void releaseSavepoint(Object savepoint)

釋放一個儲存點,如果事務提交,所有的儲存點都對被釋放,不需要手工釋放。

TransactionStatus擴充套件了SavepointManager提供了一下的方法:

boolean hasSavepoint():判斷是否在內部建立了一個儲存點。

boolean isNewTransaction():潘丹是不是一個新的事務

boolean isCompleted():判斷事務是不是已經結束:已經提交或者回滾

boolean isRollbackOnly:當前事務是否已經被標誌位rollback_only

void setRollbackOnly:將當前的事務設定為rollback_only.

PlatformTransactionManager:

public interface PlatformTransactionManager {

	/**
	 * Return a currently active transaction or create a new one, according to
	 * the specified propagation behavior.
	 * <p>Note that parameters like isolation level or timeout will only be applied
	 * to new transactions, and thus be ignored when participating in active ones.
	 * <p>Furthermore, not all transaction definition settings will be supported
	 * by every transaction manager: A proper transaction manager implementation
	 * should throw an exception when unsupported settings are encountered.
	 * <p>An exception to the above rule is the read-only flag, which should be
	 * ignored if no explicit read-only mode is supported. Essentially, the
	 * read-only flag is just a hint for potential optimization.
	 * @param definition TransactionDefinition instance (can be {@code null} for defaults),
	 * describing propagation behavior, isolation level, timeout etc.
	 * @return transaction status object representing the new or current transaction
	 * @throws TransactionException in case of lookup, creation, or system errors
	 * @throws IllegalTransactionStateException if the given transaction definition
	 * cannot be executed (for example, if a currently active transaction is in
	 * conflict with the specified propagation behavior)
	 * @see TransactionDefinition#getPropagationBehavior
	 * @see TransactionDefinition#getIsolationLevel
	 * @see TransactionDefinition#getTimeout
	 * @see TransactionDefinition#isReadOnly
	 */
	TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

	/**
	 * Commit the given transaction, with regard to its status. If the transaction
	 * has been marked rollback-only programmatically, perform a rollback.
	 * <p>If the transaction wasn't a new one, omit the commit for proper
	 * participation in the surrounding transaction. If a previous transaction
	 * has been suspended to be able to create a new one, resume the previous
	 * transaction after committing the new one.
	 * <p>Note that when the commit call completes, no matter if normally or
	 * throwing an exception, the transaction must be fully completed and
	 * cleaned up. No rollback call should be expected in such a case.
	 * <p>If this method throws an exception other than a TransactionException,
	 * then some before-commit error caused the commit attempt to fail. For
	 * example, an O/R Mapping tool might have tried to flush changes to the
	 * database right before commit, with the resulting DataAccessException
	 * causing the transaction to fail. The original exception will be
	 * propagated to the caller of this commit method in such a case.
	 * @param status object returned by the {@code getTransaction} method
	 * @throws UnexpectedRollbackException in case of an unexpected rollback
	 * that the transaction coordinator initiated
	 * @throws HeuristicCompletionException in case of a transaction failure
	 * caused by a heuristic decision on the side of the transaction coordinator
	 * @throws TransactionSystemException in case of commit or system errors
	 * (typically caused by fundamental resource failures)
	 * @throws IllegalTransactionStateException if the given transaction
	 * is already completed (that is, committed or rolled back)
	 * @see TransactionStatus#setRollbackOnly
	 */
	void commit(TransactionStatus status) throws TransactionException;

	/**
	 * Perform a rollback of the given transaction.
	 * <p>If the transaction wasn't a new one, just set it rollback-only for proper
	 * participation in the surrounding transaction. If a previous transaction
	 * has been suspended to be able to create a new one, resume the previous
	 * transaction after rolling back the new one.
	 * <p><b>Do not call rollback on a transaction if commit threw an exception.</b>
	 * The transaction will already have been completed and cleaned up when commit
	 * returns, even in case of a commit exception. Consequently, a rollback call
	 * after commit failure will lead to an IllegalTransactionStateException.
	 * @param status object returned by the {@code getTransaction} method
	 * @throws TransactionSystemException in case of rollback or system errors
	 * (typically caused by fundamental resource failures)
	 * @throws IllegalTransactionStateException if the given transaction
	 * is already completed (that is, committed or rolled back)
	 */
	void rollback(TransactionStatus status) throws TransactionException;

}


5 程式設計式事務管理

TransactionTemplate和那些持久化模板類一樣,是執行緒安全的。

Object execute(TransactionCallback action) :在TransactionCallBack回撥介面中定義需要以事務方式組織的資料訪問邏輯。 

public class Forum1Service {
	private TransactionTemplate template;
	
	public void addForum(){
		template.execute(new TransactionCallbackWithoutResult() {
			
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus status) {
				//需要在事務環境中執行的程式碼
			}
		});
	}
	
}

6 使用XML宣告事務

7 使用註解宣告事務