【发布时间】:2017-04-12 20:35:03
【问题描述】:
嗯,这是我的第一篇文章,所以我真的必须摸不着头脑,因为这里的资源非常好。
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 列保留为空等数据库错误时,它不会回滚。
上面的引号是故意的,因为我意识到它实际上并没有像我想的那样从“进程”方法中的错误成功回滚,因为它还没有写入数据库。退出时执行此操作。
数据库错误发生在流程方法和调用pojo之间。 Hibernate 已存储第一级数据并开始将所有对象写入数据库。
我已经尝试在“进程”方法中对所有内容进行 try/catch,但由于那里没有发生错误(当它离开方法时动作开始!)所以没有任何东西被抛出和捕获。
调用 pojo 确实捕获了一个错误(并且可以看到 not null 的数据异常错误),但它已将对象写入数据库并在错误发生之前将它们留在那里。
rollbackFor 很好,但故障似乎在那之后 - 它在该方法中捕获错误,但是当它离开该方法并且 Spring/Hibernate 完成它的事情并提交时......它留在了数据库中。没有回滚。所以 rollbackFor 似乎只适用于关联方法中的错误,而不是之后自动发生的事情(后面写)
几乎像自动提交行为,但不应该是 Hibernate (Oracle 10) 的情况。
有什么想法吗?我将在今天放入一个 flush() 以查看这是否会使错误发生在 process 方法中并因此被 rollbackFor 捕获...但我们不应该这样做吗? (如果可行的话)
谢谢
【问题讨论】:
标签: spring hibernate transactions