gpt4 book ai didi

hibernate - 尝试锁定域对象时出现 StaleObjectStateException

转载 作者:行者123 更新时间:2023-12-03 03:28:36 25 4
gpt4 key购买 nike

我最近在尝试将子对象添加到父对象的列表时遇到了一些并发修改错误。

根据我所读到的内容,添加子对象会增加父对象的版本号,因此如果另一个线程正在执行我的创建方法,它会提示。

很公平。

我返回并尝试锁定域对象,以便它会阻塞,直到上一个添加完成。令人惊讶的是,当我尝试锁定对象时,现在似乎会抛出 StaleObjectStateException!

这是我的测试代码:

  def create(User user, Company company, ReferenceCodeCommand cmd) {                                                                                                                                                                                                                                                                                   
log.debug("superbooking type: " + cmd.superBooking.getClass().getName())
cmd.superBooking.refresh();
log.debug("#" + random + " Locking superbooking: " + superBooking.id)
def superBooking = SuperBooking.lock(cmd.superBooking.id)
log.debug("#" + random + " Superbooking: " + superBooking.id + " locked")
def referenceCode = new ReferenceCode(cmd.properties)

def random = Math.random()

log.debug("#" + random + " ReferenceCode test point 1. SuperBooking version " + referenceCode.superBooking.version)
superBooking.addToRefs(referenceCode)
log.debug("#" + random + " ReferenceCode test point 2. SuperBooking version " + superBooking.version)

if (!referenceCode.hasErrors()
&& referenceCode.save(flush: true)) {
log.debug("ReferenceCode saved successfully")
} else {
log.warn("#" + random + " ReferenceCode not saved successfully ${referenceCode}.")
}
log.debug("#" + random + " ReferenceCode test point 3. SuperBooking version " + superBooking.version)
superBooking.save(flush: true, failOnError: true)
log.debug("#" + random + " ReferenceCode test point 4. SuperBooking version " + superBooking.version)

return referenceCode
}

这是一些示例输出:

2013-09-06 13:31:21,645 [http-bio-8080-exec-19] DEBUG dao.ReferenceCodeDAOService  - superbooking type: com.ngs.id.model.SuperBooking
2013-09-06 13:31:21,667 [http-bio-8080-exec-19] DEBUG dao.ReferenceCodeDAOService - #0.06947409938388194 Locking superbooking: 208535
2013-09-06 13:31:21,667 [http-bio-8080-exec-19] DEBUG dao.ReferenceCodeDAOService - #0.06947409938388194 Superbooking: 208535 locked
2013-09-06 13:31:21,667 [http-bio-8080-exec-19] DEBUG dao.ReferenceCodeDAOService - #0.06947409938388194 ReferenceCode test point 1. SuperBooking version 6
2013-09-06 13:31:21,667 [http-bio-8080-exec-19] DEBUG dao.ReferenceCodeDAOService - #0.06947409938388194 ReferenceCode test point 2. SuperBooking version 6
2013-09-06 13:31:21,701 [http-bio-8080-exec-19] DEBUG dao.ReferenceCodeDAOService - #0.06947409938388194 ReferenceCode test point 3. SuperBooking version 7
2013-09-06 13:31:21,708 [http-bio-8080-exec-19] DEBUG dao.ReferenceCodeDAOService - #0.06947409938388194 ReferenceCode test point 4. SuperBooking version 7
| Error 2013-09-06 13:31:21,715 [http-bio-8080-exec-20] ERROR errors.GrailsExceptionResolver - StaleObjectStateException occurred when processing request: [POST] /interpreter-direct/api/superBooking/208535/referenceCode/
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.ngs.id.model.SuperBooking#208535]. Stacktrace follows:
Message: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.ngs.id.model.SuperBooking#208535]

错误发生在我锁定 SuperBooking 的线路上。这真的让我感到困惑:从我读到的内容来看,lock()将从数据库中获取行并锁定它,直到事务完成。我本以为 StaleObjectStateException 在这里根本没有意义。

有人可以给我一些建议,或者其他方法吗?这对我们的应用产生了严重的影响。

谢谢!

最佳答案

我想您使用数据库锁定是为了支持可以使用同一数据库的多服务器。看起来你的代码没问题。可能导致此异常的原因是在调试时运行并在没有正确完成执行的情况下停止,因此数据库事务未提交并且锁定仍然存在。尝试在同一 cmd.superBooking.id 没有打开任何事务时执行此操作。或者测试时尝试使用不同的id。一般来说,如果您的应用程序很可能不会对同一行执行多次更新,请改用乐观锁定。 IE。不要使用锁定方法,而是使用 try 和 catch 来处理 StaleObjectException。

关于hibernate - 尝试锁定域对象时出现 StaleObjectStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18666377/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com