Spring编程式事务详解

举报
JavaEdge 发表于 2021/06/04 01:38:37 2021/06/04
【摘要】 为了更细粒度的事务划分,Spring提供两种方式的编程式事务管理。 TransactionTemplate 使用 PlatformTransactionManager 实现。 如果你选择编程式事务管理,Spring推荐使用 TransactionTemplate。 第二种方法则类似使用JTA的 UserTransaction API (除了异常处理的部分稍微简单点)...

为了更细粒度的事务划分,Spring提供两种方式的编程式事务管理。

TransactionTemplate

使用 PlatformTransactionManager 实现。
如果你选择编程式事务管理,Spring推荐使用 TransactionTemplate。
第二种方法则类似使用JTA的 UserTransaction API (除了异常处理的部分稍微简单点)。

使用TransactionTemplate

TransactionTemplate 采用与Spring中别的 模板 同样的方法, 如 JdbcTemplate 。它使用回调机制,将应用代码从样板式的资源获取和释放代码中解放出来, 这样写出的代码是目的驱动的,把精力集中在开发者想要做的事情上。

就像你马上要在后面的例子中看到的那样, 使用 TransactionTemplate 绝对会增加你的代码与Spring的事务框架和API间的耦合。 到底编程式事务管理是不是适合你的项目需要由你自己来决定。

应用代码必须在一个事务性的上下文中执行,这样就会像这样一样显式的使用TransactionTemplate。作为应用程序员, 会写一个 TransactionCallback 的实现, (通常会用匿名类来实现 )这样的实现会包含所以你需要在该事务上下文中执行的代码。
然后你会把一个你自己实现TransactionCallback的实例传递给TransactionTemplate暴露的execute 方法。

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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

如果不需要返回值,更方便的是创建一个 TransactionCallbackWithoutResult 匿名类

transactionTemplate.execute(new TransactionCallbackWithoutResult() {
  @Override
  protected void doInTransactionWithoutResult(TransactionStatus status) { updateOperation1(); updateOperation2();
  }
});

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

回调方法内的代码可以通过调用 TransactionStatus 对象的 setRollbackOnly() 方法来回滚事务。

transactionTemplate.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { try { updateOperation1(); updateOperation2(); } catch (SomeBusinessExeption ex) { status.setRollbackOnly(); }
  }
});

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

9.6.1.1. 指定事务设置
诸如传播模式、隔离等级、超时等等的事务设置都可以在TransactionTemplate中或者通过配置或者编程式地实现。 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...
  }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

在下面的例子中,我们将会演示如何使用Spring XML配置来定制TransactionTemplate的事务属性。 'sharedTransactionTemplate’可以被注入到所有需要的服务中去。




"
最后,TransactionTemplate 类的实例是线程安全的,任何状态都不会被保存。 TransactionTemplate 实例 的确会 维护配置状态,所以当一些类选择共享一个单独的 TransactionTemplate实例时, 如果一个类需要使用不同配置的TransactionTemplate(比如,不同的隔离等级), 那就需要创建和使用两个不同的TransactionTemplate。

使用PlatformTransactionManager

你也可以使用 org.springframework.transaction.PlatformTransactionManager 来直接管理你的事务。只需通过bean的引用,简单的把你在使用的PlatformTransactionManager 传递给你的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 {
  // 执行业务逻辑
}
catch (MyException ex) {
  txManager.rollback(status);
  throw ex;
}
txManager.commit(status);

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

文章来源: javaedge.blog.csdn.net,作者:JavaEdge.,版权归原作者所有,如需转载,请联系作者。

原文链接:javaedge.blog.csdn.net/article/details/113755685

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。