Spi*_*man 8 java spring hibernate transactions
我正在使用Spring和Hibernate进行事务管理.我的情况如下:
我有一个被事务所依赖的bean A,它调用bean B,它是用事务定义的,包括属性'PROPAGATION_REQUIRED'
在这种情况下,B不会打开新交易,而是使用现有交易(在日志中看到:'参与现有交易').但是,如果B中的方法将抛出一个runtimeException,在返回A的过程中它会弄脏事务并导致它被标记为回滚,即使A的外部方法将捕获异常而不会把它扔掉.我认为这种行为是错误的,在这种情况下我希望A控制事务,B不应该在任何情况下中断事务.
有没有办法定义B来打开事务,如果没有定义事务但是如果它已经在一个exising事务中并且让上层决定是提交还是回滚?
见在Spring社区线程有关此问题的答复这里.
看起来Propagation.NESTED
可以帮助您的事情:
B
失败,则以A
(而B
不是继续)开始的事务将正确回滚到保存点,然后B
再调用而无需触摸A
。B
承诺,只保存点被释放,其他什么都颁发给DB。Bascailly表示将进行的更改B
“合并”为交易A
。B
完成,在上述任何情况下,A
可以决定天气继续并提交(这将是一个真正的承诺DB,这将包括所有的变化通过A
和 B
[如果犯])或回滚(将回滚事务,直至状态创建时,使所有更改无效(A
+ B
)。配置Spring事务管理器时,可以设置名为" globalRollbackOnParticipationFailure " 的属性.如果设置为false,则参与现有事务的方法中发生的异常将不会标记要回滚的转换.如果异常被抛出启动事务的方法,则事务仅标记为回滚.
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
<property name="globalRollbackOnParticipationFailure" value="false" />
</bean>
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅JavaDoc.
理论上这是可能的,但不符合 Spring 事务方面的标准方法。您需要创建自己的方面来复制 spring 标准功能,并针对您的特殊情况进行扩展。也许甚至可以扩展他们使用的原始方面。
(不过,您可能必须定义一个自定义注释,因为您既不能覆盖 @Transactional 属性,也不能扩展 Propagation 枚举。)
以下是一些提示:
另外,即使您只想使用 Spring AOP,您也应该考虑阅读AspectJ in Action这本书,因为它提供了非常好的概述。
一个好的起点是下载spring-aspects jar 的源代码,看看它们在那里做什么,并提供您自己的扩展org.springframework.transaction.aspectj.AbstractTransactionAspect
或org.springframework.transaction.aspectj.AnnotationTransactionAspect
总结一下:我确信可以做到,但是需要做很多工作。Spring Transaction API 本身就已经相当不错了。也许你应该学会忍受它的局限性。如果没有:开始黑客攻击(见上文)
归档时间: |
|
查看次数: |
10778 次 |
最近记录: |