(我将在示例中使用Groovy / Grails语法)
在加载实体的休眠时,它们保存在会话缓存/ L1上,问题是如果在会话之外更改它们就不会被引用,即使我通过GORM方法重新查询它们。这就是我使用refresh()的原因。
(以下所有内容均在一个会话中完成。)
User.withNewTransaction {
User user = User.findById(1L, [lock: true]) //select for update
user.name='new name'
user.save()
}
//user entity gets updated on a different thread.
User.withNewTransaction {
user = User.findById(1L, [lock: true]) //another select for update
//at this point, the user entity is not yet filled in with the updated values from the different thread
//so I'm forced to do a refresh so that the user will have the correct values
user.refresh()
//update user
}
有替代方案吗?
这意味着我必须查询两次以确保我们在第二次交易中拥有正确的值。
答案 0 :(得分:-1)
是。
只需删除refresh
:
User.withNewTransaction {
user = User.findById(1L) //user = User.findById(1L, [lock: true]) //another select for update
//at this point, the user entity is not yet filled in with the updated values from the different thread
//so I'm forced to do a refresh so that the user will have the correct values
//user.refresh()
//update user
}
更好的解决方案是放弃交易!由于交易用于批次操作:
user = User.findById(1L)
如果您希望保留交易语法,那么使用withTransaction
将其加入其他正在进行的交易更有意义:
User.withTransaction {
user = User.findById(1L) //user = User.findById(1L, [lock: true]) //another select for update
//at this point, the user entity is not yet filled in with the updated values from the different thread
//so I'm forced to do a refresh so that the user will have the correct values
//user.refresh()
//update user
}
<强>综述强>
您应该很少使用refresh
,因为它会忽略 hibernate优势,除非有特殊需要指定here