(示例中我将使用Groovy/Grails语法)
在hibernate中,当一个实体被加载时,它们被保存在会话缓存/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
}
有其他选择吗?
这意味着我必须查询两次以确保我们在第二个事务中有正确的值。
是。
直接去掉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的优点,除非有特殊需要在这里指定