【问题标题】:TransactionRequiredException in a method that is already annotated with @Transactional已使用 @Transactional 注释的方法中的 TransactionRequiredException
【发布时间】:2018-10-22 04:46:56
【问题描述】:
public void postPessoa() {
    savePessoa();
    initializePessoa();
}

@Transactional(rollbackOn = {Exception.class})
public void savePessoa() {
    pessoa = getEntityManager().merge(pessoa);
}

如果我调用postPessoa(),我在merge() 中得到TransactionRequiredException,但如果我直接从JSF 调用savePessoa(),它会起作用,我不明白为什么会出现这种行为。

JSF:

<p:commandButton id="btnSalvar" value="Salvar" action="#{pessoasController.savePessoa}"/>

<p:commandButton id="btnSalvar" value="Salvar" action="#{pessoasController.postPessoa}"/>

【问题讨论】:

  • 这实际上不是 JSF 问题。如果您创建了一个好的单元测试,也会发生同样的情况
  • 可能,但我想了解为什么直接从jsf调用带注释的方法会改变事务注释的行为。
  • 这不是直接从jsf调用它而是直接调用它。看答案。顺便说一句,您使用的是spring还是cdi?答案对 spring 和 cdi 都是正确的
  • 我明白了。我正在使用 CDI,但老实说,我在问,因为我不知道我的错误是在 jsf 调用中、在事务中还是在我的 jpa 控制中。在问这里之前我搜索了很多......
  • 这就是我提到单元测试的原因。哟然后可以排除的东西。 JSF 在这种情况下

标签: jsf-2 cdi


【解决方案1】:

你必须添加

@Transactional

...在班级级别或postPessoa() 上也是如此。

来自spring-doc

在代理模式下(这是默认的),只有外部方法调用 通过代理进来的被拦截。 这意味着 自调用,实际上是目标对象调用的方法 目标对象的另一种方法,不会导致实际 运行时事务,即使调用的方法被标记为 @事务。此外,代理必须完全初始化以提供 预期的行为,因此您不应在您的 初始化代码,即@PostConstruct。

【讨论】:

  • 但它没有被传播,当“调用这个”时......这就是为什么 OR
  • @MạnhQuyếtNguyễn 这就是 Xerx593 所说的。问题是,如果它在一个方法上,它必须是一个从 bean 外部调用的方法
  • 啊哈,我被疏忽了。他的方法在一个类中被调用。不错的收获
  • @xerx593 但如果我在 postPessoa() 中添加 Transactional,则方法 initializePessoa() 将位于相同的事务上下文中,这不是我想要的还是我错了?
  • 啊哈!? (第二个 tx-context!?)你想混合吗? (请解释......听起来[艰难..不可能])
猜你喜欢
  • 2018-02-23
  • 2020-03-29
  • 2012-08-25
  • 2011-09-07
  • 2016-01-31
  • 2019-11-18
  • 2020-02-14
  • 2014-12-25
相关资源
最近更新 更多