上一篇写到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);