【问题标题】:Chained transactional api calls spring链式事务 api 调用 spring
【发布时间】:2015-03-11 11:29:30
【问题描述】:

我遇到了一个问题,我的交易没有提交

我的服务类是@Transactional 注释

@Transactional
class MyService{
   public void find();
   public void return(); //Return will only happen if find is updated in DB
   public void cancel(){
          find();
          return();
   }
}

我的班级有 3 个 api,它们在内部调用各自的 Dao,而 Dao 没有注释为 Transactional。

现在如果我调用cancel,我会先调用find,然后调用return()。但是 return() 需要 find() 需要用 FIND 状态更新数据库。

但是由于所有都发生在同一个事务上,直到返回取消,事务才被提交。有人可以帮助我了解这种情况并解决它。

我不知道在这种情况下如何使用传播。

提前谢谢..

【问题讨论】:

  • 它们使用相同的事务,这意味着事务中所做的更改对于从事务中调用的所有选择都是可见的
  • 在同一个事务本身中,即使 find() 更新了数据库,当我从 return() 检查时,我无法看到数据库已更新。

标签: java spring jpa transactional


【解决方案1】:

Spring Transcation 文档摘录 (Spring Doc)

在代理模式下(默认),只有外部方法调用 通过代理进来的被拦截。这意味着 自调用,实际上是目标对象调用的方法 目标对象的另一种方法,不会导致实际 即使调用的方法标记为 @Transactional。

在 cancel() 方法中对 find() 和 return() 的调用不是事务性的。如果您希望它具有事务性,您可以执行applicationContext.getBean(this.getClass()); 之类的操作并调用您的方法。

【讨论】:

  • 无论如何都会使用传播为来自目标对象本身的每个调用启动一个新事务。
  • 如果你像这样调用 find() applicationContext.getBean(this.getClass()).find() spring 将使用当前事务。您可以在 find() 声明中添加注释 REQUIRES_NEW,Spring 将在每次调用时启动一个新事务。
  • 从同一个 bean 调用内部的 Bean 是否安全。您能否告诉我这是否会对我的系统产生任何间接影响。因为我从来没有做过这样的事情而且这个项目是一个关键的并且应该是一致的,所以我担心访问 bean 本身内部的同一个 bean
  • 一切正常,感谢您在这方面的帮助。接受这个作为答案,让我知道使用 applicationContext 在同一个 bean 中使用 bean 的间接影响(如果有的话)
  • 事实上,当您必须使用这种“技巧”时,它表明您的架构存在问题。也许你的服务层应该重新组织,或者你应该添加一个编排层,或者意识到一些无用的层只是调用另一个层。不过就性能而言,这不是问题。
猜你喜欢
  • 1970-01-01
  • 2018-12-17
  • 2011-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-25
  • 2023-03-22
相关资源
最近更新 更多