深入理解TransactionTemplate程式設計式事務
阿新 • • 發佈:2018-12-28
- Spring可以支援程式設計式事務和宣告式事務。
- Spring提供的最原始的事務管理方式是基於
TransactionDefinition
、PlatformTransactionManager
、TransactionStatus
程式設計式事務。 - 而
TransactionTemplate
的程式設計式事務管理是使用模板方法設計模式對原始事務管理方式的封裝。
原始碼探索
檢視 TransactionTemplate
.java 原始碼
public class TransactionTemplate extends DefaultTransactionDefinition implements TransactionOperations, InitializingBean {
protected final Log logger = LogFactory.getLog(this.getClass());
private PlatformTransactionManager transactionManager;
public TransactionTemplate() {
}
public TransactionTemplate(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public TransactionTemplate(PlatformTransactionManager transactionManager, TransactionDefinition transactionDefinition) {
super(transactionDefinition);
this.transactionManager = transactionManager;
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public PlatformTransactionManager getTransactionManager() {
return this.transactionManager;
}
public void afterPropertiesSet() {
if (this.transactionManager == null) {
throw new IllegalArgumentException("Property 'transactionManager' is required");
}
}
/*
* 控制事務管理主要依賴於這個方法
*/
public <T> T execute(TransactionCallback<T> action) throws TransactionException {
if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
return ((CallbackPreferringPlatformTransactionManager)this.transactionManager).execute(this, action);
} else {
TransactionStatus status = this.transactionManager.getTransaction(this);
Object result;
try {
result = action.doInTransaction(status);
} catch (RuntimeException var5) {
this.rollbackOnException(status, var5);
throw var5;
} catch (Error var6) {
this.rollbackOnException(status, var6);
throw var6;
} catch (Exception var7) {
this.rollbackOnException(status, var7);
throw new UndeclaredThrowableException(var7, "TransactionCallback threw undeclared checked exception");
}
this.transactionManager.commit(status);
return (T) result;
}
}
private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException {
this.logger.debug("Initiating transaction rollback on application exception", ex);
try {
this.transactionManager.rollback(status);
} catch (TransactionSystemException var4) {
this.logger.error("Application exception overridden by rollback exception", ex);
var4.initApplicationException(ex);
throw var4;
} catch (RuntimeException var5) {
this.logger.error("Application exception overridden by rollback exception", ex);
throw var5;
} catch (Error var6) {
this.logger.error("Application exception overridden by rollback error", ex);
throw var6;
}
}
}
從原始碼可以看出TransactionTemplate
主要依賴於execute(TransactionCallback<T> action)
方法執行事務管理。
再來分析分析execute
方法的引數 TransactionCallback
檢視介面TransactionCallback.java
發現其僅有一個方法:
public interface TransactionCallback<T> {
T doInTransaction(TransactionStatus var1);
}
並且有一個抽象類TransactionCallbackWithoutResult
實現了介面TransactionCallback
。
public abstract class TransactionCallbackWithoutResult implements TransactionCallback<Object> {
public TransactionCallbackWithoutResult() {
}
public final Object doInTransaction(TransactionStatus status) {
this.doInTransactionWithoutResult(status);
return null;
}
protected abstract void doInTransactionWithoutResult(TransactionStatus var1);
}
所以當我們藉助TransactionTemplate.execute( ... )
執行事務管理的時候,傳入的引數有兩種選擇:
1、TransactionCallback
2、TransactionCallbackWithoutResult
兩種區別從命名看就相當明顯了,一個是有返回值,一個是無返回值。這個的選擇就取決於你是讀還是寫了。
實現案例
1、在spring配置檔案中
配置相關TransactionTemplate
示例:
<!-- 事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置 transactionTemplate -->
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
</bean>
2、對TransactionCallback進行屬性設定(該設定也可以在Spring的配置檔案中指定,看個人需求)
//設定事務傳播屬性
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
// 設定事務的隔離級別,設定為讀已提交(預設是ISOLATION_DEFAULT:使用的是底層資料庫的預設的隔離級別)
transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
// 設定是否只讀,預設是false
transactionTemplate.setReadOnly(true);
// 預設使用的是資料庫底層的預設的事務的超時時間
transactionTemplate.setTimeout(30000);
3、業務程式碼引用:
(1)藉助(TransactionCallback
)執行事務管理,既帶有返回值:
public Object getObject(String str) {
/*
* 執行帶有返回值<Object>的事務管理
*/
transactionTemplate.execute(new TransactionCallback<Object>() {
@Override
public Object doInTransaction(TransactionStatus transactionStatus) {
try {
...
//....... 業務程式碼
return new Object();
} catch (Exception e) {
//回滾
transactionStatus.setRollbackOnly();
return null;
}
}
});
}
(2)藉助(TransactionCallbackWithoutResult
)執行事務管理,既無返回值:
public void update(String str) {
/*
* 執行無返回值的事務管理
*/
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
try {
// .... 業務程式碼
} catch (Exception e){
//回滾
transactionStatus.setRollbackOnly();
}
}
});
}