这是我的第一篇文章,所以我真的一定要摸不着头脑,因为这里的资源非常好。
Spring MVC 4.2.5。 hibernate-core-5.1.0 JDK8
我遇到的问题是,当离开被调用的@Transactional方法时,事务不会回滚。我正在调用的方法有适当的设置:
@Transactional(propagation=Propagation.REQUIRED,readOnly=false,rollbackFor = Exception.class)
public byte process(CommonDataBlock commonDataBlock) throws Exception {
该方法调用dao对象,假设我们保存了大约8个对象('到数据库'),例如:
applicationPartyDao.saveApplicationParty(appParty);
典型的dao就是这样做:
this.getSessionFactory().getCurrentSession().save(appParty);
一开始,我从正常的POJO调用上述事务方法'进程':
try {
// Database transaction starts/ends here
submitAccess.process(commonDataBlock);
}
catch (Exception e) {
logUtil.debug(this, "Error submitting application: "+e.getMessage());
e.printStackTrace();
return Codes.RET_BYPASS_ALL_ADAPTORS;
}
(该评论不太正确,数据库事务以“进程”方法开始和结束。)
所以 - 当'process'中的代码出错时,它们全部'回滚'(引用故意)。但是当出现数据库错误(如FK问题或NOT NULL列)为null时,它不会回滚。
引用是故意的,因为我意识到它并没有像我想的那样从'process'方法中的错误实际上成功回滚,因为它还没有写入数据库。这是退出吗?
数据库错误发生在进程方法和调用pojo之间。 Hibernate已经存储了第一级数据并开始将所有对象写入数据库。
我已尝试在'process'方法中对所有内容进行try / catch,但因为没有错误发生(当它离开方法时动作开始了!)然后没有任何东西抛出并被捕获。
调用pojo确实捕获了一个错误(并且可以看到非null的数据异常错误),但是它已经将对象写入数据库并在错误发生之前将它们保留在那里。
rollbackFor很好,但是故障似乎是在那之后 - 它在该方法中捕获错误,但是当它离开方法并且Spring / Hibernate做了它的事情并且提交......它留在数据库上。没有回滚。所以rollbackFor似乎只适用于相关方法中的错误,而不是在(后写)
之后自动发生的事情几乎像自动提交行为,但不应该是Hibernate(Oracle 10)的情况。
有什么想法?我今天会在今天放一个flush(),看看是否会在进程方法中发生错误,因此被rollbackFor抓住......但我们不应该这样做吗? (如果有效)
由于
答案 0 :(得分:0)
知道了。问题是我要更改事务管理器的名称:
<bean id="transactionManager_guardianship" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory_guardianship" />
<property name="dataSource"><ref bean="dataSource_guardianship"/></property>
</bean>
如果你没有将它作为“transactionManager”,我会在某处读到它找不到它。有道理(我也按名称查找上下文的内容!显而易见!)。我做了这个,因为我有两个不同的数据库。
所以我添加了一个限定符:
<bean id="transactionManager_guardianship" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory_guardianship" />
<property name="dataSource"><ref bean="dataSource_guardianship"/></property>
<qualifier value="txGuardianship"/>
</bean>
...并在服务类中引用了正确的事务:
@Transactional(value="txGuardianship", propagation=Propagation.REQUIRED,readOnly=false,rollbackFor = Exception.class)
public byte process(CommonDataBlock commonDataBlock) throws Exception {
当我有两个时,这是为了更改事务管理器名称,加上(它改变的原因)。类似的@Transactional(值=另一个的设置。
干杯