【问题标题】:Hibernate transactional method call within transactional method rollback事务方法回滚中的休眠事务方法调用
【发布时间】:2013-05-05 10:11:29
【问题描述】:

我正在尝试创建一个事务方法,该方法调用其他几个事务方法以保存一些相互依赖的数据库实体。如果任何调用失败,我希望事务完全回滚。然而,这不是观察到的行为。这是我的代码:

@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
public void save(EntityToBeSaved entity) {
    try{
            for(SubEntity sub: entity.getSubEntities()) //specifics omitted
                  saveSubEntity(sub); //this is transactional
    }
    catch (DataIntegrityViolationException e){
        throw new BusinessException("Duplicate Name");
    }
}

saveSubEntity 也有 Propagation.REQUIREDrollobackFor = Throwable.class ,但是当事务在第二个 saveSubEntity 调用失败时,第一个 subEntity 被提交。

【问题讨论】:

  • 非常令人惊讶。你能显示saveSubEntity()的代码吗?此外,readOnly=false 和propagation=REQUIRED 是默认值。您可以删除这些属性。

标签: java spring hibernate annotations transactional


【解决方案1】:

也许问题是 Hibernate 无法为 save 方法打开事务。

假设如果 Hibernate 没有为 save 方法创建任何事务,那么每个 saveSubEntity 调用将由于其 Propagation.REQUIRED 而位于不同的事务中。因此,每个 saveSubEntity 调用的更改都将提交到数据库。

要检查是否为 save 方法创建了事务,您能帮我删除 saveSubEnitty 方法上的 Tranactional 注释吗.如果没有为 save 方法创建事务,您将看到一个错误。

【讨论】:

  • 您好,感谢您的帮助。我实际上放置了一个断点,并评估了 TransactionAspectSupport.currentTransactionStatus() ,它抛出了一个 NoTransactionException ,所以显然父亲没有打开一个事务,即使它有 Propagation.REQUIRED。知道为什么会这样吗?
  • 因为您使用的是基于注释的Spring Transaction,我猜您确实在应用程序上下文的Spring 配置文件中声明了标签<tx:annotation-driven/>。最后,您应该检查标签<context:component-scan> 并确保具有 save 方法的 bean 必须在 base-package 中。
  • 是的,所有这些参数都是正确的,问题在于显式的构造函数调用。
  • @Manos M:嗯,很奇怪,当服务 bean 没有被 DI 容器实例化时,你可以调用 save 方法。您是通过 new 操作还是依赖注入技术创建了服务实例?
【解决方案2】:

显然,问题是由于 Spring 注入错误导致的,因为服务在启动时没有实例化,导致注解无法正常工作。谢谢你的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2011-06-23
    • 2011-10-18
    相关资源
    最近更新 更多