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