【发布时间】:2015-03-07 03:34:05
【问题描述】:
@Transactional (noRollbackFor=RuntimeException.class)
public void methodA (Entity e){
service.methodB(e);
}
---下面的服务方法---
@Transactional (propagation=Propagation.REQUIRES_NEW, noRollbackFor=RuntimeException.class)
public void methodB (Entity e){
dao.insert(e);
}
当methodB() 中的dao.insert(e) 导致主键冲突并引发ConstraintViolationException(RuntimeException 的子类)时,由于我使用了noRollbackFor 属性,我预计事务仍将提交。但我观察到外部事务(在methodA 上)仍然被HibernateTransactionManager 回滚并显示消息
org.springframework.transaction.UnexpectedRollback 异常: 事务回滚,因为它已被标记为仅回滚
我发现报告了类似的问题,但不完全是这个。
【问题讨论】:
-
您是否将 globalRollbackOnParticipationFailure 设置为 false 例如
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="globalRollbackOnParticipationFailure" value="false" /> <property name="sessionFactory" ref="sessionFactory" /> </bean> -
很确定 sol4me 是在正确的轨道上 - 请参阅 stackoverflow.com/a/11205537/1594449
-
听起来是个好主意,但我并不热衷于更改
globalRollbackOnParticipationFailure的设置,因为我正在增强已经使用相同事务管理器的现有单片代码,我想保留现有代码不受我的更改影响 - 通过更改 tx 管理器配置似乎不可行。我可以做一些完全针对我的改变的事情吗? -
仅供参考,我还尝试在
dao.insert(e);中捕获RuntimeException中的methodB并在将其包装在检查异常中后将其重新抛出。我更改了noRollbackFor以匹配使用的检查异常。然而,这并没有什么不同——methodA中的外部事务仍然被回滚! -
@ankur-singhal - 因为 methodB 正在开始一个新事务,所以谁为 methodA 启动事务有关系吗?
标签: java spring hibernate jpa transactions