Spring - 事務管理



資料庫事務是一系列被視為單個工作單元的操作。這些操作應該要麼完全完成,要麼完全無效。事務管理是面向RDBMS的企業應用程式的重要組成部分,用於確保資料完整性和一致性。事務的概念可以用以下四個關鍵屬性來描述,稱為ACID

  • 原子性 - 事務應被視為單個操作單元,這意味著要麼整個操作序列成功,要麼失敗。

  • 一致性 - 這表示資料庫參照完整性、表中唯一主鍵等的一致性。

  • 隔離性 - 可能會有許多事務同時處理相同的資料集。每個事務都應與其他事務隔離,以防止資料損壞。

  • 永續性 - 一旦事務完成,此事務的結果必須永久儲存,並且由於系統故障而不能從資料庫中刪除。

真實的RDBMS資料庫系統將保證每個事務的這四個屬性。使用SQL向資料庫發出事務的簡單檢視如下:

  • 使用begin transaction命令開始事務。

  • 使用SQL查詢執行各種刪除、更新或插入操作。

  • 如果所有操作都成功,則執行commit,否則rollback所有操作。

Spring框架在不同的底層事務管理API之上提供了一個抽象層。Spring的事務支援旨在透過向POJO新增事務功能來提供EJB事務的替代方案。Spring支援程式化和宣告式事務管理。EJB需要應用程式伺服器,但是Spring事務管理無需應用程式伺服器即可實現。

本地事務與全域性事務

本地事務特定於單個事務資源(如JDBC連線),而全域性事務可以跨越多個事務資源,例如分散式系統中的事務。

本地事務管理在應用程式元件和資源位於單個站點且事務管理僅涉及在單個機器上執行的本地資料管理器的情況下非常有用。本地事務更容易實現。

在分散式計算環境中,所有資源都分佈在多個系統中,需要全域性事務管理。在這種情況下,需要在本地和全域性級別進行事務管理。分散式事務或全域性事務跨多個系統執行,其執行需要全域性事務管理系統與所有相關係統的所有本地資料管理器之間進行協調。

程式化與宣告式

Spring支援兩種型別的事務管理:

  • 程式化事務管理 - 這意味著您必須藉助程式設計來管理事務。這為您提供了極大的靈活性,但難以維護。

  • 宣告式事務管理 - 這意味著您將事務管理與業務程式碼分開。您只需使用註解或基於XML的配置來管理事務。

儘管宣告式事務管理不如程式化事務管理靈活,後者允許您透過程式碼控制事務,但宣告式事務管理更可取。但是,作為一種橫切關注點,宣告式事務管理可以透過AOP方法進行模組化。Spring透過Spring AOP框架支援宣告式事務管理。

Spring事務抽象

Spring事務抽象的關鍵由org.springframework.transaction.PlatformTransactionManager介面定義,如下所示:

public interface PlatformTransactionManager {
   TransactionStatus getTransaction(TransactionDefinition definition);
   throws TransactionException;
   
   void commit(TransactionStatus status) throws TransactionException;
   void rollback(TransactionStatus status) throws TransactionException;
}

序號 方法及描述
1

TransactionStatus getTransaction(TransactionDefinition definition)

此方法根據指定的傳播行為返回當前活動事務或建立新事務。

2

void commit(TransactionStatus status)

此方法提交給定事務,並考慮其狀態。

3

void rollback(TransactionStatus status)

此方法回滾給定事務。

TransactionDefinition是Spring事務支援的核心介面,其定義如下:

public interface TransactionDefinition {
   int getPropagationBehavior();
   int getIsolationLevel();
   String getName();
   int getTimeout();
   boolean isReadOnly();
}

序號 方法及描述
1

int getPropagationBehavior()

此方法返回傳播行為。Spring提供所有從EJB CMT熟悉的事務傳播選項。

2

int getIsolationLevel()

此方法返回此事務與其他事務工作的隔離程度。

3

String getName()

此方法返回此事務的名稱。

4

int getTimeout()

此方法返回事務必須完成的時間(秒)。

5

boolean isReadOnly()

此方法返回事務是否為只讀。

以下是隔離級別的可能值:

序號 隔離級別及描述
1

TransactionDefinition.ISOLATION_DEFAULT

這是預設的隔離級別。

2

TransactionDefinition.ISOLATION_READ_COMMITTED

指示髒讀被阻止;不可重複讀和幻讀可能會發生。

3

TransactionDefinition.ISOLATION_READ_UNCOMMITTED

指示髒讀、不可重複讀和幻讀都可能發生。

4

TransactionDefinition.ISOLATION_REPEATABLE_READ

指示髒讀和不可重複讀被阻止;幻讀可能會發生。

5

TransactionDefinition.ISOLATION_SERIALIZABLE

指示髒讀、不可重複讀和幻讀都被阻止。

以下是傳播型別的可能值:

序號 傳播型別及描述
1

TransactionDefinition.PROPAGATION_MANDATORY

支援當前事務;如果沒有當前事務,則丟擲異常。

2

TransactionDefinition.PROPAGATION_NESTED

如果存在當前事務,則在巢狀事務中執行。

3

TransactionDefinition.PROPAGATION_NEVER

不支援當前事務;如果存在當前事務,則丟擲異常。

4

TransactionDefinition.PROPAGATION_NOT_SUPPORTED

不支援當前事務;而是始終非事務性地執行。

5

TransactionDefinition.PROPAGATION_REQUIRED

支援當前事務;如果不存在,則建立一個新的。

6

TransactionDefinition.PROPAGATION_REQUIRES_NEW

建立一個新事務,如果存在當前事務則掛起。

7

TransactionDefinition.PROPAGATION_SUPPORTS

支援當前事務;如果不存在,則非事務性地執行。

8

TransactionDefinition.TIMEOUT_DEFAULT

使用底層事務系統的預設超時,或者如果不支援超時則為無。

TransactionStatus介面為事務程式碼提供了一種簡單的方法來控制事務執行和查詢事務狀態。

public interface TransactionStatus extends SavepointManager {
   boolean isNewTransaction();
   boolean hasSavepoint();
   void setRollbackOnly();
   boolean isRollbackOnly();
   boolean isCompleted();
}

序號 方法及描述
1

boolean hasSavepoint()

此方法返回此事務是否內部包含儲存點,即是否已基於儲存點建立為巢狀事務。

2

boolean isCompleted()

此方法返回此事務是否已完成,即它是否已提交或回滾。

3

boolean isNewTransaction()

如果當前事務是新的,則此方法返回true。

4

boolean isRollbackOnly()

此方法返回事務是否已被標記為僅回滾。

5

void setRollbackOnly()

此方法將事務設定為僅回滾。

廣告