【问题标题】:PROPAGATION_REQUIRED transaction attribute in spring?春天的 PROPAGATION_REQUIRED 事务属性?
【发布时间】:2011-08-10 18:06:46
【问题描述】:

http://www.vermatech.com/code/SpringTransactionExamples.html 给出的第一个案例研究中, 程序正在调用两个方法,即

testModel.deleteAllCountries();
testModel.initializeCountries();

initializeCountries 抛出运行时异常。对于这两种方法的事务定义属性都是 PROPAGATION_REQUIRED。 deleteAllCountries 下的仍然事务 方法被提交,但 initializeCountries 下的事务被回滚(根据同一案例研究中给出的日志)。

根据 PROPAGATION_REQUIRED 的定义是它支持当前事务;如果不存在,则创建一个新的。所以我的问题是initializeCountries方法下的事务 应该支持 deleteAllCountries 方法下的事务。我的意思是这两种方法都应该被视为单一交易。根据我的理解,应该提交还是回滚完整的事务?不知道日志是如何将它们分开处理的。

【问题讨论】:

    标签: java spring jakarta-ee spring-transactions


    【解决方案1】:

    “需要传播”定义为

    支持当前事务,如果不存在则创建一个新事务。

    在上述情况下,deleteAllCountries 方法在事务中执行并提交。调用 initializeCountries 时没有当前事务,所以它在第二个事务中执行,回滚对第一个方法所做的更改没有影响。

    传播适用于嵌套的方法调用,而不是连续的。如果你看the documentation

    当传播设置为 PROPAGATION_REQUIRED 时,逻辑 为设置所在的每个方法创建事务范围 应用。每个这样的逻辑事务范围都可以确定 单独回滚状态,具有外部事务范围 在逻辑上独立于内部事务范围。的 当然,在标准 PROPAGATION_REQUIRED 行为的情况下,所有这些 范围将映射到相同的物理事务。所以一个 在内部事务范围内设置的仅回滚标记确实会影响 外部事务实际提交的机会(如您所料 它到)。

    但是,在内部事务范围设置 rollback-only 标记,外部事务尚未决定 回滚本身,因此回滚(由内部无声触发 事务范围)是意外的。对应的 此时会引发 UnexpectedRollbackException。这是预期的 行为使交易的调用者永远不会被误导 假设实际上没有执行提交。所以如果一个 内部事务(外部调用者不知道)静默 将事务标记为仅回滚,外部调用者仍然调用 犯罪。外部调用者需要收到一个 UnexpectedRollbackException 清楚地表明回滚是 而是执行。

    然后你可以看到所有这些都是关于内部和外部的,没有一个提到连续的调用。在您的情况下,对 deleteAllCountries 的调用是最外层的事务方法,因此当它成功完成时,Spring 会立即提交事务。然后您对 initializeCountries 的调用必须在单独的事务中执行,它是最外层的方法。

    您的假设似乎是 Spring 将在第一个方法完成后保持事务打开,但这不是它的工作方式。为了获得您想要的效果,您可以在 testModel 上创建另一个方法来包装对 deleteAllCountries 和 initializeCountries 的调用,使该方法具有事务性并为其赋予属性 PROPAGATION_REQUIRED。这样,第二个方法的回滚将导致第一个方法的更改也被回滚,因为包装方法将它们组合在一起。否则没有什么告诉 Spring 这些东西应该是同一个事务的一部分。

    【讨论】:

    • 谢谢内森。但是通过链接后得到了更多问题。有两种说法。 Statement1 - 每个这样的逻辑事务范围都可以单独确定仅回滚状态,外部事务范围在逻辑上独立于内部事务范围。 Statement2 - 当然,在标准 PROPAGATION_REQUIRED 行为的情况下,所有这些范围都将映射到同一个物理事务。因此,在内部事务范围内设置的仅回滚标记确实会影响外部事务实际提交的机会(正如您所期望的那样)。
    • 在 statement1 中哪个是外部事务,哪个是内部事务。在 Statemt2 中:- 这里是相同的物理交易
    • @Mohit:关键是两者都不是外在的或内在的,这是不适用的。
    • 其实 nathan 我正在尝试获取语句的含义“但是,在内部事务范围设置仅回滚标记的情况下,外部事务尚未决定回滚本身,因此回滚(由内部事务范围静默触发)是意外的。此时会引发相应的 UnexpectedRollbackException。”抱歉,您能否通过一些简短的示例帮助我理解内部交易条款和外部交易条款?提前致谢
    • @mohit:在我建议的修复中,包装器方法是外部的,现有的方法是内部的。但是让我们看看还有什么其他答案,也许有人可以比我更好地解释它。有一些非常可靠的专家应该看到这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-27
    • 2015-06-06
    • 1970-01-01
    • 2018-11-29
    • 2018-07-26
    • 2016-12-09
    • 1970-01-01
    相关资源
    最近更新 更多