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;
}