TransactionTemplate 采用了与其他 Spring 模板相同的方法,例如 JdbcTemplate。它使用回调方法(使应用程序代码不必做模板式的获取和释放交易资源),并导致代码是意图驱动的,即你的代码只关注你想做的事情。
:::info 正如下面的例子所示,使用 TransactionTemplate 绝对能让你与 Spring 的事务基础设施和 API 结合起来。编程式事务管理是否适合你的开发需求,你必须自己做出决定。 :::
必须在事务性上下文中运行并且明确使用 TransactionTemplate 的应用程序代码类似于下一个例子。你,作为一个应用程序的开发者,可以写一个 TransactionCallback 的实现(通常表示为一个匿名的内部类),其中包含你需要在事务上下文中运行的代码。然后你可以把你的自定义 TransactionCallback 的一个实例传递给 TransactionTemplate 上暴露的 execute(..)
方法。下面的例子显示了如何做到这一点:
public class SimpleService implements Service {
// 这个实例中的所有方法都共享一个 TransactionTemplate
private final TransactionTemplate transactionTemplate;
// 使用构造函数注入来提供 PlatformTransactionManager。
public SimpleService(PlatformTransactionManager transactionManager) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
public Object someServiceMethod() {
return transactionTemplate.execute(new TransactionCallback() {
// 该方法中的代码在事务性环境中运行
public Object doInTransaction(TransactionStatus status) {
updateOperation1();
return resultOfUpdateOperation2();
}
});
}
}
如果没有返回值,你可以使用方便的 TransactionCallbackWithoutResult 类与一个匿名类,如下所示:
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
updateOperation1();
updateOperation2();
}
});
回调中的代码可以通过调用所提供的 TransactionStatus 对象的 setRollbackOnly()
方法来回滚事务,如下所示:
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
try {
updateOperation1();
updateOperation2();
} catch (SomeBusinessException ex) {
status.setRollbackOnly();
}
}
});
指定事务设置
你可以通过编程或配置在 TransactionTemplate 上指定事务设置(如传播模式、隔离级别、超时等等)。默认情况下,TransactionTemplate 实例有 默认的事务设置。下面的例子显示了对一个特定的 TransactionTemplate 的事务性设置的程序化定制:
public class SimpleService implements Service {
private final TransactionTemplate transactionTemplate;
public SimpleService(PlatformTransactionManager transactionManager) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
// 如果需要,可以在这里明确设置事务设置
this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
this.transactionTemplate.setTimeout(30); // 30 seconds
// and so forth...
}
}
下面的例子通过使用 Spring 的 XML 配置,定义了一个带有一些自定义事务性设置的 TransactionTemplate:
<bean id="sharedTransactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="isolationLevelName" value="ISOLATION_READ_UNCOMMITTED"/>
<property name="timeout" value="30"/>
</bean>
然后,你可以根据需要将 sharedTransactionTemplate 注入到许多服务中。
最后,TransactionTemplate 类的实例是线程安全的,因为实例不维护任何对话状态。然而,TransactionTemplate 实例确实维护配置状态。因此,虽然许多类可以共享 TransactionTemplate 的一个实例,但如果一个类需要使用具有不同设置的 TransactionTemplate(例如,不同的隔离级别),你需要创建两个不同的 TransactionTemplate 实例。