有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在spring中是否需要事务属性?

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

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

其中initializeCountries引发运行时异常。对于这两种方法,都需要“事务定义”属性。仍在删除所有国家/地区下进行交易 方法被提交,但initializeCountries下的事务被回滚(根据同一案例研究中给出的日志)

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


共 (1) 个答案

  1. # 1 楼答案

    “需要传播”定义为

    Support a current transaction, create a new one if none exists.

    在上面的例子中,deleteAllCountries方法在事务中执行并提交。调用initializeCountries时没有当前事务,因此它在第二个事务中执行,回滚它对第一个方法所做的更改没有影响

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

    When the propagation setting is PROPAGATION_REQUIRED, a logical transaction scope is created for each method upon which the setting is applied. Each such logical transaction scope can determine rollback-only status individually, with an outer transaction scope being logically independent from the inner transaction scope. Of course, in case of standard PROPAGATION_REQUIRED behavior, all these scopes will be mapped to the same physical transaction. So a rollback-only marker set in the inner transaction scope does affect the outer transaction's chance to actually commit (as you would expect it to).

    However, in the case where an inner transaction scope sets the rollback-only marker, the outer transaction has not decided on the rollback itself, and so the rollback (silently triggered by the inner transaction scope) is unexpected. A corresponding UnexpectedRollbackException is thrown at that point. This is expected behavior so that the caller of a transaction can never be misled to assume that a commit was performed when it really was not. So if an inner transaction (of which the outer caller is not aware) silently marks a transaction as rollback-only, the outer caller still calls commit. The outer caller needs to receive an UnexpectedRollbackException to indicate clearly that a rollback was performed instead.

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

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