zoukankan      html  css  js  c++  java
  • org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction

    今天排查项目问题,发现这样一个异常:

    org.springframework.orm.ObjectOptimisticLockingFailureException: Object of class [...] with identifier [9941E59B5B1D48248AB8
    B58EDF2767CC]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or
    unsaved-value mapping was incorrect) : [...]
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:298)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:225)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:484)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
    ...
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.commons.beanutils.MethodUtils.invokeMethod(MethodUtils.java:281)
    at org.apache.commons.beanutils.MethodUtils.invokeMethod(MethodUtils.java:225)
    ...
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:115)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
    Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [...]
    at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:2541)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3285)
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:3183)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3525)
    at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:159)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:465)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:351)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1258)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
    at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:77)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
    ... 28 common frames omitted

    项目使用spring data jpa hibernate框架

    错误原因是多个线程同时访问了数据库的一条数据,并修改(或者删除)了这条数据。在前一个线程操作后,后一个线程也对这条数据进行操作,这时后一个线程拿到的数据是第一个线程操作前的版本,这个时候操作数据就会出现问题。

    参考了网上的答案,大概有两种解决办法:

    1.使用悲观锁处理查询到的数据:使用sql查询,并加上for update(sql结构为 select ... for update)

    update)

    2.当要操作数据前,重新查询数据(通过id查询),尽可能拿到数据库中最新的数据,并在操作数据后flush()方法,将数据立刻更新到数据库

    参考:

    1.Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : https://stackoverflow.com/questions/8645694/row-was-updated-or-deleted-by-another-transaction-or-unsaved-value-mapping-was?r=SearchResults

  • 相关阅读:
    iOS App Store审核上传应用预览视频
    mac 下常用命令(xcode常用命令,环境相关等)
    Xcode遇到的一些常见异常
    Tomcat的SSL配置keytool生成证书
    iOS Developer TODO
    Linix常用命令
    iOS&OSX系统初步了解
    Mac下安装MySQL及启动等常用命令
    Android WebView存在跨域访问漏洞(CNVD-2017-36682)介绍及解决
    HTML5 Audio/Video 标签,属性,方法,事件汇总 (转)
  • 原文地址:https://www.cnblogs.com/xhj123/p/12371529.html
Copyright © 2011-2022 走看看