锁定 Grails 不起作用
我在 Grails 中使用锁时遇到一些问题。
情况如下:
我有一个 User 类,然后是另一个 UserProperty 类,它有一个 belognsTo=User 属性。
现在,为了避免用户同时修改此属性,我想锁定用户,然后修改/添加/删除新属性。
但锁似乎不起作用,因为在这两种情况下请求都会失败。伪代码看起来像这样:
User.lock(userId)
log.info "Starting modifiying properties"
addRemoveOrChangePropertiesToUser(userId)
log.info "Finsih modifing properties"
User.save(flush: true)
我期望的行为是,第一个请求将通过并记录所有内容。直到那时(因为用户被锁定)第二个请求等待,然后对属性进行更改。
根据日志文件,我看到了完全不同的行为。两个请求都得到处理,无需任何等待时间(几乎同时)。
你知道我做错了什么吗?我是否误解了一些与数据库锁定相关的概念?我怎样才能达到预期的行为?
谢谢, 尼古拉斯
I'm facing some issues while using the lock in Grails.
The situation is the following:
I have a User class, and then another Class UserProperty which has a belognsTo=User Property.
Now to avoid the user concurrently modifing this properties I want to lock the user, and after that modify/add/delete new properties.
But the lock seems not to be working, since in both cases the request goes trough. The pseudocode looks something like this:
User.lock(userId)
log.info "Starting modifiying properties"
addRemoveOrChangePropertiesToUser(userId)
log.info "Finsih modifing properties"
User.save(flush: true)
The behavior that I'm expecting is, that the first request goes through and logs everything. And till that (since user is locked) the second request waits and then does the changes to the properties.
Based on the log files, I see a completetly different behavior. Both requests are processed without any waiting time (almos simultationiusly).
Do you have any idea, what am I doing wrong? Did I missunderstand some of the Concepts related to the db locking? How can I achieve the desired behavior?
Thanks,
Nicolas
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我刚刚遇到了类似的问题,我的功能在控制器中。我认为一旦命中 .lock 语句,其他线程就应该被阻止,但这并没有发生。将整个事情包装在一个事务中解决了我的问题。
所以像这样的事情:
事后看来,我想这是有道理的。我怀疑事务需要提供明确的划分(工作单元),否则 GORM/hibernate 如何知道何时可以释放锁?
控制器方法有一个开放的会话,但没有包装在事务中。默认情况下,服务方法包装在事务中,我怀疑我们不会在那里看到这个问题。
I just ran into a similar problem where my function was in a controller. I thought that other threads should be blocked once hitting the .lock statement, but that wasn't happening. Wrapping the whole thing in a transaction fixed the problem for me.
So something like this:
In hindsight this makes sense I guess. I suspect the transaction is required to provide a clear demarcation (a unit of work) otherwise how does GORM/hibernate know when it can release the lock?
Controller methods have an open session but are not wrapped in a transaction. Service methods are wrapped in a transaction by default and I suspect we would not see this issue there.
我不确定这锁是如何工作的。据我了解,当其他人从休眠会话获取实体时,它会锁定该实体,防止其他人更新同一实例。
I'm not sure this is how the lock works. It's my understanding that it locks the entity from OTHERS updating the same instance when they obtain it from the hibernate session.
我不确定你是否正确实施了这一点。我认为您需要获取一个实例 - 然后像...一样锁定它,
然后尝试修改锁定的实例。
I'm not sure you're implementing this correctly. I think you need to obtain an instance - then lock it like...
And then try to modify the locked instance.