我有一个在网络服务器上运行的Java项目。我总是碰到这个例外。
我阅读了一些文档,发现悲观锁定(或乐观,但我阅读悲观更好)是防止此异常的最佳方法。
但是我找不到任何清晰的示例来说明如何使用它。
我的方法是这样的:
@Transactional
Public void test(Email email, String Subject){
getEmailById(String id);
email.setSubject(Subject);
updateEmail(email);
}
而:
Email
是一个hibernate类(它将是数据库中的一个表)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
通常不建议使用悲观锁定,因为从数据库方面考虑,这种锁定的成本很高。您所提到的问题(代码部分)尚不清楚,例如:
session
对象(不确定是否使用Spring)?hibernate会话对象不是线程安全的。因此,如果有多个线程访问同一个会话并尝试更新同一个数据库实体,则您的代码可能最终会出现这样的错误情况。
因此,这里发生的事情是,有多个线程尝试更新同一实体,一个线程成功,当下一个线程提交数据时,它看到其已被修改并最终抛出StaleObjectStateException
。
编辑 :
在Hibernate中有一种使用悲观锁定的方法。查看此链接。但是这种机制似乎存在一些问题。但是,我偶然发现了一个hibernate状态的错误(HHH-5275)。该错误中提到的情况如下:
两个线程正在读取同一数据库记录;这些线程中的一个应使用悲观锁定,从而阻止另一个线程。但是两个线程都可以读取数据库记录,从而导致测试失败。
这与您所面临的非常接近。如果这不起作用,请尝试此操作,我能想到的唯一方法是使用本机SQL查询,在该查询中可以使用查询在postgres数据库中实现悲观锁定SELECT FOR UPDATE
。
问题内容: 我阅读了一些文档,发现悲观锁定(或乐观,但我阅读悲观更好)是防止此异常的最佳方法。 但是我找不到任何清晰的示例来说明如何使用它。 我的方法是这样的: 而: 是一个hibernate类(它将是数据库中的一个表) 是返回的函数(此方法未使用注释) :是一种更新电子邮件的方法。 注:我使用Hibernate进行保存,更新和等(例如:) 例外: 问题答案: 常不建议使用悲观锁定,就数据库方面的
问题内容: 不幸的是,简单地返回’{}’,这意味着a在还原后变成空对象。 我发现es6-mapify允许在Map和普通对象之间进行上/下转换,所以这可能是一种解决方案,但是我希望我仅需要使用外部依赖项来持久保存我的地图。 问题答案: 假设您的键和值都是可序列化的, 应该管用。反之,使用
我想删除所有的组,其中一个用户是所有者,但它目前不起作用。我认为在映射用户的级别上存在一些不足之处。哈佛商学院。xml或组。哈佛商学院。但是我不知道。错误是“无法删除或更新父行:外键约束失败(,约束外键()引用()” 以下是与xml相关的类和文件: 使用者JAVA 用户道 使用者哈佛商学院。xml 组哈佛商学院。xml UserDaoTest。JAVA
我有两个对象实体(用户和电话),它们应该有多对多关系。 使用者JAVA 电话JAVA 现在,我在用户表中添加了两个ID为1和2的用户。然后,我添加一个id为1的手机,并将它们映射到两个用户id(1) 我的用户电话表如下所示: 现在,我想删除一个ID为2的用户。当我尝试这样做时,我得到了一个错误 我的删除脚本: 知道我哪里出错了吗?非常感谢:)
我有父实体和一个方向作为具有关系的子实体。我尝试使用Hibernate查询删除超过一周的广告,但得到的结果是: com.mysql.jdbc.exceptions.jdbc4.mysqlintegrityConstraintViolationException:无法删除或更新父行:外键约束失败(.,constraint外键()引用() 用户: 筛选器: 广告: DAO删除方法:
如何在不删除索引映射的情况下从elasticsearch数据库中删除数据? 我是Tire gem,使用删除命令删除我所有的映射并再次运行创建命令。我想避免创建命令一次又一次地运行。 请帮我解决这个问题。