【问题标题】:Spring @transactional not auto rolling back during unchecked exceptionSpring @transactional 在未经检查的异常期间不会自动回滚
【发布时间】:2018-12-24 00:46:33
【问题描述】:

A类{

@transactional 公共无效方法A(){

方法B();

int i=10/0;

}

@transactional 公共无效方法B(){

session.save(学生)

}

这里methodA有异常,但是没有回滚插入学生数据,为什么?

}

【问题讨论】:

  • 把所有配置放在问题上。以便于识别问题
  • 这段代码不会编译
  • methodA 是从另一个类调用的吗?只有当您跨越类边界时,才会捕获(激活?)Spring 注释。
  • 两种方法都在同一个类中

标签: java spring hibernate transactional


【解决方案1】:

默认情况下,@Transactional 回滚运行时异常。

你需要使用rollbackFor()。

@Transactional(rollbackFor = {MyException.class})

【讨论】:

  • 是的,我知道它会因运行时异常而回滚。但在这种情况下,它不会回滚...除以零是运行时异常,对吗?
【解决方案2】:

标有@Transactional 的方法必须是public

这记录在Spring Manual chapter 10.5.6:

方法可见性和@Transactional

使用代理时,您应该申请 仅限 @Transactional 注释 到具有公共可见性的方法。如果 您确实注释了受保护的、私有的或 包可见的方法 @Transactional注解,没有错误 被提出,但带注释的方法 不显示配置的 交易设置。考虑 如果需要,使用 AspectJ(见下文) 注释非公共方法。

【讨论】:

  • 只公开
【解决方案3】:

因为 A 和 B 分开交易!

当您在事务块中调用没有@Transactional 的方法时,父事务将继续使用新方法。它将使用来自父方法的相同连接(带有@Transactional)以及在被调用方法中引起的任何异常(不带@Transactional)将导致事务按照事务定义中的配置回滚。

如果您在同一实例中从带有@Transactional 的方法调用带有@Transactional 注释的方法,则被调用的方法的事务行为不会对事务产生任何影响。但是如果你从另一个具有事务定义的方法调用具有事务定义的方法,并且它们在不同的实例中,那么被调用方法中的代码将遵循被调用方法中给出的事务定义。

您可以在spring transaction documentation的声明式事务管理部分找到更多详细信息。

Spring 声明式事务模型使用 AOP 代理。所以 AOP 代理负责创建事务。仅当实例中的方法从实例外部调用时,AOP 代理才会处于活动状态。

【讨论】:

    【解决方案4】:

    答案取决于您已经知道的内容。

    你知道添加@Transactional注解时Spring是如何工作的吗? Ans: 它通过为具有注释方法的类创建代理类来实现。

    你知道当代理类中的一个方法调用同一个代理类中的另一个方法时 Spring Proxy 对象是如何工作的吗? Ans: Sprig 无法隐式处理这种情况。被调用方法上的任何注释都将被忽略(因为调用发生在“this”而不是代理上) 您需要切换到 AspectJ 来处理此类场景的

    如果您真的想了解这种行为,我建议您阅读 Spring 文档的这一部分。

    猜你喜欢
    • 2020-10-18
    • 2019-06-30
    • 1970-01-01
    • 2017-12-07
    • 2021-03-23
    • 2015-03-21
    • 2015-02-12
    • 1970-01-01
    • 2021-02-22
    相关资源
    最近更新 更多