Grails:获取/解决“无法将数据库状态与会话同步”?

时间:2012-10-18 14:44:07

标签: hibernate session grails

这个问题的根源是什么,导致失败同步的原因是什么?这是一个通用消息,只是意味着“出了问题”或者会话本身有什么问题吗? 有一些线程具有相似的标题,但似乎没有一个实际解决hibernate未能同步会话的原因,它只是人们忽略的错误消息的一部分。

我的具体案例/细节(虽然它与上述问题非常相似):

在导入数据(20-120分钟)期间,我正在进行大量处理。在构建并验证整个域对象集以保持一致性之前,不会开始持久性。在这段时间里,我构建了大约200,000个域对象。在该过程结束时,它循环遍历它们,将它们全部保存到数据库中(出于性能原因)在每50或100个对象之后刷新/清除会话。一旦持久性开始,域对象就不会被更改。

这一切都发生在单个服务调用中,即单个事务。我也无法在我的测试系统上重现这一点,它只发生在生产中。

我使用domainObj.save()而不是session.saveOrUpdate(domainObj),我手动触摸会话的唯一一次是在一系列更新后刷新/清理它:

def session = sessionFactory.currentSession
session.flush()
session.clear()

这是抛出异常的地方。

在失败同步消息之后立即(可能是结果,但可能与原因相关):

Could not execute JDBC batch update; SQL [insert into domainB(field1, field2, etc) values (?, ?, ?)];  
nested exception is org.hibernate.exception.ConstrainViolationException: Could not execute JDBC batch update

我意识到这个ConstrainViolation(是的,“约束”而非“约束”)似乎是一个数据错误,但数据集一直在工作,并且无需更改导入文件或代码,就开始抛出此错误。它还继续在其他系统上工作,所以我在相对一定程度上排除了数据错误。

由于对象关系的性质,我几乎肯定了相同的对象被多次保存。这是性能改进的另一个方面,但我认为是不相关的,因为一旦对象被保存,它应该分配ID并重新保存不应该导致错误。

此时我已经偏离了漫无目的和猜测,我不希望有人为我解决我的问题,但希望有人明确知道有关同步会话的事情而不是“你确定你没有插入重复数据?“因为我尽可能地确定(使用约束唯一字段作为查找要保存的域对象的键来迭代Hashmap.keySet())。

1 个答案:

答案 0 :(得分:2)

不幸的是,我仍然不知道如何实际调试“无法将数据库状态与会话同步”,但我最终能够解决这个问题。

显然,数据库使用的Oracle表空间没有设置增长,而且已经填满了。将表空间设置为“可扩展”后,此错误消失。我非常怀疑这会帮助遇到同样问题的其他人,因为错误信息不适用,但是,你永远不会知道。