自动刷新/提交离开事务方法期间的春季休眠回滚失败



这是我的第一篇文章,所以我真的一定很挠头,因为这里的资源非常好。

春季 MVC 4.2.5。 休眠核心-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);

典型的道只是做这样的事情:

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;
}

(该注释不太正确,数据库事务以"进程"方法开始和结束。

所以 - 当"进程"中的代码中存在错误时,它都会"回滚"(故意引号)。但是,当出现数据库错误(例如 FK 问题或 NOT NULL 列保留为 null)时,它不会回滚。

上面的引号是故意的,因为我意识到它实际上并没有像我想象的那样从"进程"方法中的错误中成功回滚,因为它还没有写入数据库。在退出时执行此操作。

数据库错误发生在进程方法和调用 pojo 之间。Hibernate已经存储了第一级数据,并开始将所有对象写入数据库。

我尝试在"进程"方法中的所有内容周围进行尝试/捕获,但是由于那里没有发生错误(当它离开方法时,操作开始了!),因此没有任何抛出和捕获。

调用 pojo 确实捕获了错误(并且可以看到非 null 的数据异常错误),但它已将对象写入数据库并在错误之前将它们留在那里。

回滚是好的,但错误似乎是在那之后 - 它在该方法中捕获错误,但是当它离开该方法并且 Spring/Hibernate 执行其操作并提交时......它留在数据库中。无回滚。所以 rollbackFor 似乎仅适用于关联方法中的错误,而不是之后自动发生的情况(写在后面)

几乎就像自动提交行为一样,但Hibernate(Oracle 10)不应该如此。

有什么想法吗?我今天将放入一个 flush(),看看这是否使错误在进程方法中发生,从而被回滚捕获...但我们不应该这样做吗?(如果可行)

谢谢

知道了。问题是我会更改事务管理器的名称:

<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>

我会在某处读到,如果你没有它作为"事务管理器",它不会找到它。有道理(我也按名称查找上下文内容! 显而易见!我这样做是因为我有两个不同的数据库。

所以我添加了一个限定符:

<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(值=另一个的设置。

干杯

最新更新