上一篇写到spring的声明式事务管理
spring同样也提供两种编程式事管理
1.使用TransactionTemplate
2.直接使用一个PlatformTransactionManager实现
如果使用编程式事务管理的方式,应该尽量采用TransactionTemplate
TransactionTemplate采用与spring中别的模板(如jdbcTemplate)同样的方法,它使用回调机制,将应用代码从资源获取和释放代码中解放出来,这样写出的代码是目的驱动的,把精力集中在开发者想做的事情上面。但是使用TransactionTemplate绝对会增加你的代码与spring事务框架和api间的耦合,具体的事务管理方式还是要根据不同的情况选择。
如下:
public class SimpleService implements Service {
in this instance
private final TransactionTemplate transactionTemplate;
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() {
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 (SomeBusinessExeption ex) {
status.setRollbackOnly();
}
}
});
诸如传播模式、隔离等级、超时等等的事务设置都可以在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);
this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
this.transactionTemplate.setTimeout(30); // 30 seconds
}
}
TransactionTemplate
实例是线程安全的,任何状态都不会保存,TransactionTemplate
会维护配置的状态,所以当一些类共享一个单独的TransactionTemplate
实例时候,不需要考虑安全性的问题,但是如果一个类需要不同配置的TransactionTemplate
,比如不同的隔离登记,那就需要创建两个不同的的TransactionTemplate
。
第二种方式是PlatformTransactionManager
我们可以直接使用PlatformTransactionManager
管理我们的事务,只需要通过bean的应用,简单的把正在使用的PlatformTransactionManager
传递给bean,然后,使用TransactionDefinition
和TransactionStatus
对象,可以启动,回滚和提交事务,
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = txManager.getTransaction(def);
try {
}
catch (MyException ex) {
txManager.rollback(status);
throw ex;
}
txManager.commit(status);