休眠是否对分离对象有默认的乐观锁定?
我有一个应用程序:
void deleteObj(id){
MyObj obj = getObjById(id);
if (obj == null) {
throw new CustomException("doesn't exists");
}
em.remove(obj);//em is a javax.persistence.EntityManager
}
我没有显式配置 乐观锁定与版本字段。但是,如果两个请求并行运行,试图删除同一个对象,那么我有时会得到一个 HibernateOptimisticLockingFailureException,有时会得到“CustomException”。
在没有显式设置乐观锁定的情况下获得 HibernateOptimisticLockingFailureException 是否正常?休眠是否为分离的对象提供默认的乐观锁定?
您正在做什么来处理这个 HibernateOptimisticLockingFailureException ?重试或使用“服务器繁忙”等默认消息通知用户?
I have an application that does:
void deleteObj(id){
MyObj obj = getObjById(id);
if (obj == null) {
throw new CustomException("doesn't exists");
}
em.remove(obj);//em is a javax.persistence.EntityManager
}
I haven't explicitly configure optimistic locking with version field.However, if two request are running in parallel, trying to delete the same object, then I get sometimes an HibernateOptimisticLockingFailureException and other times the "CustomException".
Is it normal to get HibernateOptimisticLockingFailureException without explicitly setting optimistic locking ? Does hibernate a default optimistic locking for detached objects ?
What are you doing to handle this HibernateOptimisticLockingFailureException ? Retry or inform to the user with a default message like "server busy" ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先, < code>HibernateOptimisticLockingFailureException是Spring持久化异常转换机制的结果。它是为了响应 < code>StaleStateException,其 javadoc 说:
从常识来看,当数据修改语句返回意外数量的受影响行时,就会发生乐观锁异常。这可能是由于版本值不匹配以及根本不存在该行引起的。
为了确保实体确实被删除,您可以在删除后立即尝试通过 em.flush() 刷新上下文并捕获它抛出的异常(请注意,它应该是 PersistenceException 的子类 有
StaleStateException
作为原因)。First of all,
HibernateOptimisticLockingFailureException
is a result of Spring's persistence exception translation mechanism. It's thrown in response toStaleStateException
, whose javadoc says:From the common sense, optimistic lock exception occurs when data modification statement returns unexpected number of affected rows. It may be caused by mismatch of version value as well as by absence of the row at all.
To make sure that entity was actually removed you can try to flush the context by
em.flush()
right after removing and catch an exception thrown by it (note that it should be subclass ofPersistenceException
havingStaleStateException
as a cause).