简体   繁体   English

Grails:乐观锁定,StaleObjectStateException与Spring Security会话中的域,更新计数器

[英]Grails: Optimistic locking, StaleObjectStateException with domain on session with Spring Security, updating counters

I have a Grails app where people login through Spring Security. 我有一个Grails应用程序,人们可以在其中通过Spring Security登录。 Their user domain is then loaded onto the session for the duration of being logged in. 然后,在登录期间,将其用户域加载到会话上。

I get a StaleObjectStateException when another user preforms an action that updates a counter on a user object in the database user.save(flush:true) that's currently on another session of a logged in user 当另一个用户执行一个操作来更新数据库user.save(flush:true)中当前在登录用户的另一个会话上的用户对象上的计数器时,出现user.save(flush:true)

Eg I have "User A" object on the session for logged in User A. Then when a User B is logged in, and preforms an action to update the User A object but the version is out of sync. 例如,我在会话中具有用于登录用户A的“用户A”对象。然后,当用户B登录时,执行一个操作来更新用户A对象,但版本不同步。

org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.example.User#2]

        at $Proxy12.merge(Unknown Source) 

I've tried merging but no luck. 我尝试合并,但没有运气。

I'm thinking of completely taking out the "version" property as there are so many updates on the user domain as hundreds of users would be logged in. But I don't know what affect this would have on the consistency of the data over time. 我正在考虑完全删除“版本”属性,因为用户域上的更新如此之多,将导致数百名用户登录。但是我不知道这会对数据一致性产生什么影响时间。

Would swapping user.save(flush:true) to User.executeUpdate(Update viewCount where ...) solve the problem and bring more caching issues? user.save(flush:true)交换到User.executeUpdate(Update viewCount where ...)解决问题并带来更多的缓存问题吗?

Or can I select specific properties that can ignore "version" when updating them. 或者我可以选择在更新它们时可以忽略“版本”的特定属性。 I don't really understand whats going on though with this example. 我对这个例子不太了解。 http://grails.1312388.n4.nabble.com/GORM-setting-access-field-td1592837.html http://grails.1312388.n4.nabble.com/GORM-setting-access-field-td1592837.html

So how can I solve this? 那么我该如何解决呢?

Solved: Basically don't have the user domain on the session. 解决:基本上在会话中没有用户域。 Just the users Id. 只是用户ID。 So you can load the domain when you need to use it. 因此,您可以在需要使用域时加载它。

The solution is not to use a domain object inside the session. 解决方案是不要在会话内部使用域对象。 Use the id instead, and then load the object for each request that needs the user data. 改用id,然后为需要用户数据的每个请求加载对象。 It's differences introduced in spring security plugin for grails. 它是针对grails的spring安全插件中引入的差异。 For more info have a look here (official docs): 有关更多信息,请在此处查看(官方文档):

http://burtbeckwith.github.com/grails-spring-security-core/docs/manual/guide/2%20Differences%20Between%20the%20Spring%20Security%20and%20Acegi%20Plugins.html http://burtbeckwith.github.com/grails-spring-security-core/docs/manual/guide/2%20Differences%20Between%20the%20Spring%20Security%20and%20Acegi%20Plugins.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM