M S*_*ach 3 java spring java-ee spring-transactions
在http://www.vermatech.com/code/SpringTransactionExamples.html上的第一个案例研究中,程序正在调用两个方法,即
testModel.deleteAllCountries();
testModel.initializeCountries();
Run Code Online (Sandbox Code Playgroud)
其中initializeCountries抛出运行时异常.对于这两种方法,事务定义属性为PROPAGATION_REQUIRED.仍然会在deleteAllCountries方法下提交事务,但会回滚initializeCountries下的事务(根据同一案例研究中给出的日志).
根据PROPAGATION_REQUIRED定义,它支持当前事务; 如果不存在则创建一个新的.所以我的问题是在initializeCountries方法下的事务应该支持deleteAllCountries方法下的事务.我的意思是这两种方法都应该被视为单一交易.根据我的理解,还是应该提交或回滚完整的事务?不知道日志是如何分别处理它们的.
Nat*_*hes 12
"需要传播"定义为
支持当前事务,如果不存在则创建新事务.
在上面的例子中,deleteAllCountries方法在事务中执行并提交.调用initializeCountries时没有当前事务,因此它在第二个事务中执行,并且回滚它对第一个方法所做的更改没有影响.
传播适用于嵌套方法调用,而不适用于连续调用.如果你看一下文档:
当传播设置为PROPAGATION_REQUIRED时,将为应用该设置的每个方法创建逻辑事务范围.每个这样的逻辑事务范围可以单独确定仅回滚状态,外部事务范围在逻辑上独立于内部事务范围.当然,在标准PROPAGATION_REQUIRED行为的情况下,所有这些范围将映射到同一物理事务.因此,内部事务范围中的仅回滚标记集确实会影响外部事务实际提交的机会(正如您所期望的那样).
但是,在内部事务作用域设置仅回滚标记的情况下,外部事务尚未决定回滚本身,因此回滚(由内部事务作用域静默触发)是意外的.此时抛出相应的UnexpectedRollbackException.这是预期的行为,因此事务的调用者永远不会被误导,假设在实际上没有执行提交.因此,如果内部事务(外部调用者不知道)以静默方式将事务标记为仅回滚,则外部调用者仍会调用commit.外部调用者需要接收UnexpectedRollbackException以清楚地指示已执行回滚.
那么你可以看到所有这些都是关于内在和外在的 - 没有一个提到连续的呼叫.在您的情况下,对deleteAllCountries的调用是最外层的事务方法,因此当它成功完成时,Spring会立即提交事务.然后你对initializeCountries的调用必须在一个单独的事务中执行,它是最外层的方法.
您的假设似乎是Spring将在第一个方法完成后保持事务处于打开状态,但这不是它的工作原理.为了获得您想要的效果,您可以在testModel上创建另一个方法,该方法包含对deleteAllCountries和initializeCountries的调用,使该方法具有事务性并为其提供属性PROPAGATION_REQUIRED.这样,第二种方法的回滚将导致第一种方法的更改也被回滚,因为包装方法将它们组合在一起.否则什么都没有告诉Spring这些东西应该是同一个交易的一部分.
| 归档时间: |
|
| 查看次数: |
11826 次 |
| 最近记录: |