从 Hibernate Optimistic Locking 异常中恢复

Posted

技术标签:

【中文标题】从 Hibernate Optimistic Locking 异常中恢复【英文标题】:Recover from Hibernate Optimistic Locking exception 【发布时间】:2020-04-29 09:19:55 【问题描述】:

我最近遇到了一个奇怪的问题。我试图优雅地处理陈旧状态异常。但是在 catch 块中它仍然抛出异常。以下是代码sn -p

public void saveObject(Object ob)
   try
      sessionFactory.getCurrentSession().saveOrUpdate(ob);
   catch(org.springframework.orm.hibernate5.HibernateOptimisticLockingFailureException e)
       object latestObject = // get latest object from db;
       copyFieldsFromObToLatestObject(ob,latestObject);
       // print the version of of both object

    LOGGER.info(" ui_version="+ob.getVersion().longValue()+" 
                 entity_version="+latestObject.getVersion().longValue());
          // the ui _version is less than entity_ version as expected 

        sessionFactory.getCurrentSession().saveOrUpdate(latestObject); // at this line I still get the same optimistic locking exception 

   

 /**

 ob2 is the latest object which contains the correct  version hence copying the fields from previous object to this latest object
**/
private void copyFieldsFromObToLatestObject(ob1,ob2)
    ob2.setA(ob1.getA())..
   so on

有人可以看看这个。我无法得到正确处理后仍然抛出乐观锁定异常的原因

EDIT 1堆栈跟踪

org.springframework.orm.hibernate5.HibernateOptimisticLockingFailureException:批量更新从更新[0]返回了意外的行数;实际行数:0;预期:1;嵌套异常是 org.hibernate.StaleStateException:批量更新从更新 [0] 返回了意外的行数;实际行数:0;预期:1 [信息] 在 org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:283) [信息] 在 org.springframework.orm.hibernate5.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:755) [信息] 在 org.springframework.orm.hibernate5.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:590) [信息] 在 org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:765) [信息] 在 org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:734) [信息] 在 org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:518) [信息] 在 org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292) [信息] 在 org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) [信息] 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [信息] 在 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) [信息] 在 com.sun.proxy.$Proxy155.saveOrUpdate(未知来源) [信息] 在 biz.kaar.common.services.appointment.impl.AppointmentServiceExtension1BOImpl.handleStaleStateException(AppointmentServiceExtension1BOImpl.java:1520) [信息] 在 biz.kaar.common.services.appointment.impl.AppointmentServiceExtension1BOImpl.saveSAR(AppointmentServiceExtension1BOImpl.java:845) [信息] 在 biz.kaar.common.services.DBServiceImpl.saveSAR(DBServiceImpl.java:382) [INFO] 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [信息] 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [信息] 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [INFO] 在 java.lang.reflect.Method.invoke(Method.java:498) [信息] 在 net.sf.gilead.gwt.PersistentRemoteService.processCall(PersistentRemoteService.java:115) [信息] 在 biz.kaar.common.security.AuthorizedGWTServlet.processCall(AuthorizedGWTServlet.java:252) [信息] 在 biz.kaar.common.services.RemoteServletWithLogging.processCall(RemoteServletWithLogging.java:90) [信息] com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:373) [信息] 在 com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62) [信息] 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:707) [信息] 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [信息] 在 org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812) [信息] 在 org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669) [信息] 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316) [INFO] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityIntercep

【问题讨论】:

能否请您发布异常和您获得的堆栈跟踪 编辑了问题。请看一下 【参考方案1】:

在 catch 块中,您应该捕获抛出的并要处理的异常。你抓住Optimistic locking exception。我什至无法想象这是如何编译的。尝试用堆栈跟踪中的异常名称替换它?

【讨论】:

【参考方案2】:

问题已解决,我也在 to 字段中复制关联子实体的版本,这导致旧版本的子实体被保存,从而导致错误

【讨论】:

以上是关于从 Hibernate Optimistic Locking 异常中恢复的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate 如何在提交事务之前对 Optimistic Locking 进行行版本检查

乐观锁的实现

如何在 Hibernate 中使用 pooled-lo 优化器

Optimistic concurrency control

Optimistic React Apollo ui lag with React Beautiful Drag and Drop

Pessimistic and Optimistic locking