Spring Framework提供了两种方式的编程式事务管理:
1. 使用TransactionTemplate
2. 直接使用PlatformTransactionManager的一个实现
如果我们要进行编程式事务管理,一般都推荐使用TransactionTemplate方式。
TransactionTemplate方式
TransactionTemplate采用了像JdbcTemplate等其他Spring的templates的一样的回调方式。
应用代码必须在事务上下文中执行, 并且必须显式地使用TransactionTemplate。我们需要编写一个TransactionCallback的实现类(通常是一个匿名内部类)来包含需要在事务上下文中执行的代码。然后将自定义的TransactionCallback的实例传递给在TransactionTemplate的execute(..)方法。
我们来看一下Spring官方提供的示例代码:
public class SimpleService implements Service {
// single TransactionTemplate shared amongst all methods in this instance
private final TransactionTemplate transactionTemplate;
// use constructor-injection to supply the PlatformTransactionManager
public SimpleService(PlatformTransactionManager transactionManager) {
Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
public Object someServiceMethod() {
return transactionTemplate.execute(new TransactionCallback() {
// the code in this method executes in a transactional context
public Object doInTransaction(TransactionStatus status) {
updateOperation1();
return resultOfUpdateOperation2();
}
});
}
}
如果没有返回值的话, 使用TransactionCallbackWithoutResult的匿名类。再来看一下Spring官方提供的示例代码:
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 (SomeBusinessExeption ex) {
status.setRollbackOnly();
}
}
});
传播行为、隔离级别、超时时间都可以通过TransactionTemplate设置。我们看一下如何进行TransactionTemplate的事务配置。
public class SimpleService implements Service {
private final TransactionTemplate transactionTemplate;
public SimpleService(PlatformTransactionManager transactionManager) {
Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");
this.transactionTemplate = new TransactionTemplate(transactionManager);
// the transaction settings can be set here explicitly if so desired
this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
this.transactionTemplate.setTimeout(30); // 30 seconds
// and so forth...
}
}
也可以使用Spring XML配置文件来定义TransactionTemplate。这个sharedTransactionTemplate可以被注入到很多需要的服务里面。
<bean id="sharedTransactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="isolationLevelName" value="ISOLATION_READ_UNCOMMITTED"/>
<property name="timeout" value="30"/>
</bean>"
尽管许多的类可以共享一个 TransactionTemplate的单例, 但如果某一个类需要TransactionTemplate拥有不一样的设置,那么就需要创建两个或更多个TransactionTemplate的不同实例。
PlatformTransactionManager方式
可以直接使用org.springframework.transaction.PlatformTransactionManager来管理事务。只需简单的将所使用的PlatformTransactionManager的实现类通过一个bean引用传递给你自己的bean。然后,你就可以使用TransactionDefinition和TransactionStatus对象来新建事务、回滚和提交。
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// explicitly setting the transaction name is something that can only be done programmatically
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = txManager.getTransaction(def);
try {
// execute your business logic here
}
catch (MyException ex) {
txManager.rollback(status);
throw ex;
}
txManager.commit(status);