@Override
@Transactional(rollbackFor = { RuntimeException.class, Exception.class}, propagation = Propagation.REQUIRED)
public String upload(ObjectVO vo) throws CustomException {
.......
}
在这项服务中,我插入两个表。如果在处理第一个表之后插入第二个表的数据(如强制字段检查)时出现异常,它是否应该回滚同一事务中第一个表中插入的数据?在我的情况下,我没有得到回滚。预期的行为是什么? (是的,我没有捕获异常,它是一个包含在rollbackFor
子句中的自定义异常,并且正在被抛出)
(I am using hibernate
)
DAO层执行getSession().save(entity);
(getSession()
返回currentSession)
(所以第一张表中的数据仍然存在)
这些表格无关。
<tx:annotation-driven/>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
lazy-init="true">
<property name="dataSource" ref="dataSource" />
</bean>
答案 0 :(得分:1)
您确定代理实际上是否适用于方法调用?
假设您使用经典动态代理(而不是aspectJ),您是否可以确保从其类外部调用该方法?
[修改强>]
如果您正在使用休眠,请将您的事务管理器切换为HibernateTransactionManager
答案 1 :(得分:1)
第一: 如建议的那样,首先通过在log4j中添加以下内容来启用日志
log4j.category.org.springframework=ALL
第二: 如果你从同一个Servcie类中的另一个方法调用upload方法(比如xxxMethod),并且xxxMethod没有被Transaction注释。然后就不会有任何回滚。 因为Spring上下文不处理代理方法到方法之间的调用。因此它无法包装交易。
如果Second无效,请启用日志验证日志。您的日志应显示事务何时开始以及何时结束以及将哪些方法添加到事务上下文中。
如下所示
DEBUG org.springframework.transaction.annotation.AnnotationTransactionAttributeSource - Adding transactional method 'saveDomain' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2014-04-04 10:25:24,276 [main] TRACE org.springframework.orm.jpa.JpaTransactionManager - Triggering beforeCompletion synchronization
2014-04-04 10:25:24,276 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Initiating transaction rollback
所以
注意**,如果DAO图层也使用Transaction注释,传播规则为Propagation.REQUIRES_NEW
- Dao方法被视为单独的UoW。因此,从服务层抛出异常不会回滚上一个事务。
一般情况下 - 建议将交易保留在一个层中,最好是Service - Layer
答案 2 :(得分:0)
transactionManager.setRollbackOnCommitFailure(真);
您也可以使用调试器并在TransactionManager的实现中捕获执行。你有一个像回滚的方法,你会看到这个操作被省略的原因。