【问题标题】:Grails: Getting/solving "Could not synchronize database state with session"?Grails:获取/解决“无法将数据库状态与会话同步”?
【发布时间】:2012-10-18 14:44:07
【问题描述】:

这个问题的根源是,什么会导致同步失败?这是一条通用消息,仅表示“出了点问题”,还是会话本身确实有问题? 有一些标题相似的线程,但似乎没有一个能真正解决 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(是的,“constrain”而不是“constraint”)似乎是一个数据错误,但数据集一直在工作,并且在没有更改导入文件或代码的情况下开始抛出此错误。它在其他系统上也继续工作,所以我已经在一定程度上排除了数据错误。

我几乎可以肯定,由于对象关系的性质,相同的对象会被多次保存。这是另一个提高性能的地方,但我认为这无关紧要,因为一旦保存了对象,就应该为其分配 ID,并且重新保存不会导致错误。

在这一点上我已经离题了,我不希望有人为我解决我的问题,但希望有人明确了解有关同步会话的内容,而不是“你确定你没有插入重复数据?”因为我尽可能确定(使用受约束的唯一字段作为键来查找要保存的域对象,遍历 Hashmap.keySet())。

【问题讨论】:

    标签: hibernate session grails


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 2017-06-18
      • 1970-01-01
      • 2013-09-04
      • 2013-07-01
      • 2011-05-27
      • 1970-01-01
      • 2011-04-18
      • 2012-06-28
      相关资源
      最近更新 更多