spring StaleObjectStateException:行已被另一个事务更新或删除?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18597892/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 06:12:20  来源:igfitidea点击:

StaleObjectStateException: Row was updated or deleted by another transaction?

springhibernategrailsgormgrails-2.0

提问by

I do the following:

我执行以下操作:

def currentUser = springSecurityService.currentUser
currentUser.name = "test"
currentUser.save(flush: true)

// some other code

currentUser.gender = "male"
currentUser.save(flush: true)        // Exception occurs

This is the exception I get:

这是我得到的例外:

ERROR events.PatchedDefaultFlushEventListener  - Could not synchronize database state with session
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)

How can I prevent this error? What is the best solution for that?

我怎样才能防止这个错误?什么是最好的解决方案?

I found different approaches:

我发现了不同的方法:

  1. herethat you can use discard()
  2. herethat you can use merge()
  1. 在这里你可以使用discard()
  2. 在这里你可以使用merge()

Which one should I use?

我应该使用哪一种?

采纳答案by Anuj Aneja

You should use merge - it will update the object to match the current state in the database. If you use discard it will reset the object back to what the database has, discarding any changes. Everything else in the hibernate session you need to manage yourself.

您应该使用合并 - 它会更新对象以匹配数据库中的当前状态。如果你使用discard,它会将对象重置回数据库所拥有的对象,丢弃任何更改。您需要自行管理休眠会话中的所有其他内容。

More importantly code should be written in a service so that there is a database transaction, and you should use

更重要的代码应该写在一个服务中,以便有一个数据库事务,你应该使用

save(flush:true) 

once only at the end.

只在最后一次。

def currentUser = springSecurityService.currentUser
currentUser.name = "test"

//    currentUser.save(flush: true) // removing this line because if a rollback occurs, then changes before this would be persisted.


// some other code

currentUser.gender = "male"
currentUser.merge()                 // This will merge persistent object with current state
currentUser.save(flush: true)