天天看點

Spring聲明式事務詳解(上)1 事務管理2 事務抽象

1 事務管理

  • 提供的統一的API接口支援不同的資源
  • 提供聲明式事務管理
  • 友善的與Spring架構內建
  • 多個資源的事務管理、同步

2 事務抽象

2.1 事務管理器 - PlatformTransactionManager

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

2.2 事務定義 - TransactionDefinition

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

2.3 事務隔離機制

TransactionDefinition.ISOLATION_DEFAULT
TransactionDefinition.ISOLATION_READ_COMMITTED
TransactionDefinition.ISOLATION_READ_UNCOMMITTED
TransactionDefinition.ISOLATION_REPEATABLE_READ
TransactionDefinition.ISOLATION_SERIALIZABLE      

2.4 事務傳播機制

TransactionDefinition接口定義了如下int 常量:

PROPAGATION_REQUIRED (Default)

支援目前事務; 如果不存在,請建立一個新的。事務定義的預設設定,并且定義了事務同步的作用域

PROPAGATION_SUPPORTS

支援目前事務; 如果不存在,則以非事務方式執行。

對于具有事務同步的事務管理器, PROPAGATION_SUPPORTS與根本沒有事務略有不同,因為它定義了同步可能适用的事務範圍。 結果,将為整個指定範圍共享相同的資源(JDBC Connection ,Hibernate Session等)。

準确的行為取決于事務管理器的實際同步配置!

通常,請謹慎使用PROPAGATION_SUPPORTS ! 特别是,不要依賴PROPAGATION_SUPPORTS範圍内的

  • PROPAGATION_REQUIRED
  • PROPAGATION_REQUIRES_NEW (這可能會在運作時導緻同步沖突)

如果這種嵌套是不可避免的,請確定正确配置事務管理器(通常切換為“實際事務同步”)

PROPAGATION_MANDATORY

PROPAGATION_REQUIRES_NEW

PROPAGATION_NOT_SUPPORTED

不支援目前事務;而是始終以非事務方式執行。類似于同名的EJB事務屬性。

實際的事務中止将無法在所有事務管理器中立即使用。 這尤其适用于org.springframework.transaction.jta.JtaTransactionManager ,它要求javax.transaction.TransactionManager對其可用(在标準Java EE中是特定于伺服器的)。

事務同步在PROPAGATION_NOT_SUPPORTED作用域内不可用。 現有同步将被挂起并适時恢複

TransactionDefinition.PROPAGATION_NEVER

不支援目前事務;如果目前事務存在,則抛異常。類似于同名的EJB事務屬性。事務同步在PROPAGATION_NEVER作用域内不可用

  • PROPAGATION_NESTEDED
  • REQUIRED

    适用于增删改

  • SUPPORTS

    适用于查詢。

TransactionStatus

Spring提供了PlatformTransactionManager表示事務管理器,所有事務都由它管理。

而事務由TransactionStatus表示。

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

如果手寫事務代碼,使用try…catch如下:

TransactionStatus tx = null;
try {
    // 開啟事務:
    tx = txManager.getTransaction(new DefaultTransactionDefinition());
    // 相關JDBC操作:
    jdbcTemplate.update("...");
    jdbcTemplate.update("...");
    // 送出事務:
    txManager.commit(tx);
} catch (RuntimeException e) {
    // 復原事務:
    txManager.rollback(tx);
    throw e;
}