Строка была обновлена ​​или удалена другой транзакцией (или отображение несохраненных значений было неверным) - PullRequest
55 голосов
/ 27 декабря 2011

У меня есть проект Java, который работает на веб-сервере.Я всегда сталкиваюсь с этим исключением.

Я прочитал некоторую документацию и обнаружил, что пессимистическая блокировка (или оптимистическая, но я читал, что пессимистическая лучше) - лучший способ предотвратить это исключение.

НоЯ не смог найти четкого примера, который объясняет, как его использовать.

Мой метод похож на:

@Transactional
Public void test(Email email, String Subject){
   getEmailById(String id);
   email.setSubject(Subject);
   updateEmail(email);
}

, а:

  • Emailкласс гибернации (это будет таблица в базе данных)
  • getEmailById(String id) - это функция, которая возвращает email (этот метод не аннотирован @Transctional)
  • updateEmail(email): метод обновления электронной почты.

Примечание: Я использую hibernate для сохранения, обновления и т. д. (пример: session.getcurrentSession.save(email))

Исключение:

ERROR 2011-12-21 15:29:24,910 Could not synchronize database state with session [myScheduler-1]
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [email#21]
    at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1792)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2435)
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2335)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2635)
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:115)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy130.generateEmail(Unknown Source)
    at com.admtel.appserver.tasks.EmailSender.run(EmailNotificationSender.java:33)
    at com.admtel.appserver.tasks.EmailSender$$FastClassByCGLIB$$ea0d4fc2.invoke(<generated>)
    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
    at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:55)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
    at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:50)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
    at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:50)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
    at com.admtel.appserver.tasks.EmailNotificationSender$$EnhancerByCGLIB$$33eb7303.run(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:273)
    at org.springframework.scheduling.support.MethodInvokingRunnable.run(MethodInvokingRunnable.java:65)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:51)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:204)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:680)
ERROR 2011-12-21 15:29:24,915 [ exception thrown < EmailNotificationSender.run() > exception message Object of class [Email] with identifier [211]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [Email#21] with params ] [myScheduler-1]
org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException: Object of class [Email] with identifier [21]: optimistic locking failed; nested exception is 

Ответы [ 17 ]

1 голос
/ 05 ноября 2014

Эта ошибка произошла для меня, когда я пытался обновить одну и ту же строку из двух разных сеансов. Я обновил поле в одном браузере, пока открыт второй, и уже сохранил исходный объект в своем сеансе. Когда я пытался выполнить обновление из этого второго «устаревшего» сеанса, я получаю ошибку устаревшего объекта. Чтобы исправить это, я перезагружаю свой объект для обновления из базы данных, прежде чем установить значение для обновления, а затем сохраняю его как обычно.

1 голос
/ 23 мая 2014

У меня возникла та же проблема в другом контексте моего проекта, и есть разные сценарии, такие как

 - object is accessed from various source like (server side and client)
 - without any interval accessing the same object from a different place

В первом случае

Когда я выполняю команду cal, перед тем как сохранить этот объект своим одним вызовом из js и попытаться сохранить и другое место, я понял, что вызов js выполняется два, три раза (то есть вызов связывания вызывает проблему )

Я решил

e.preventDefault()

Второй случай,

object.lock()
0 голосов
/ 10 января 2019

Я также получил такое исключение, но проблема была в моем идентификаторе сущности. Я использую UUID, и есть некоторые проблемы в том, как Spring работает с ними. Поэтому я просто добавил эту строку в свой идентификатор объекта, и он начал работать:

@Column(columnDefinition = "BINARY(16)")

Здесь Вы можете найти немного больше информации.

0 голосов
/ 24 октября 2018

Я тоже сталкивался с этой проблемой.Сначала проверьте импорт, когда вы используете сеанс, транзакция должна быть org.hibernate и удалите аннотацию @Transactinal.и самое важное в классе Entity, если вы использовали @GeneratedValue (стратегии = GenerationType.AUTO) или что-либо другое, тогда во время создания объекта модели / создания объекта сущности не следует создавать идентификатор.окончательный вывод: если вы хотите передать идентификатор, то есть PK, затем удалите @GeneratedValue из класса сущностей.

0 голосов
/ 04 мая 2017

У меня была такая же проблема в моем проекте Grails.Ошибка была в том, что я переписал метод получения поля коллекции.Это всегда возвращало новую версию коллекции в другом потоке.

class Entity {
    List collection

    List getCollection() {
        return collection.unique()
    }
}

Решением было переименовать метод получения:

class Entity {
    List collection

    List getUniqueCollection() {
        return collection.unique()
    }
}
0 голосов
/ 30 октября 2015

Чтобы предотвратить StaleObjectStateException, в свой файл hbm напишите следующий код:

<timestamp name="lstUpdTstamp" column="LST_UPD_TSTAMP" source="db"/>
0 голосов
/ 22 апреля 2015

У меня была эта проблема в одном из моих приложений, теперь я знаю, что это старая ветка, но вот мое решение;По данным внутри отладчика я выяснил, что JVM фактически не загружает их должным образом, когда Hibernate пытается обновить базу данных (что на самом деле делается в другом потоке), поэтому я добавил ключевое слово «volatile» в каждое полесущностей.Для этого есть некоторые проблемы с производительностью, а не тяжелые объекты, разбросанные вокруг ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...