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

回调方法中的代码可以通过TransactionStatussetRollbackOnly() 方法来回滚事务

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,然后,使用TransactionDefinitionTransactionStatus对象,可以启动,回滚和提交事务,

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);