我在应用服务器上运行了一个spring MVC应用程序。对应用程序的每个请求都会导致Hibernate调用entityManager.merge()来更新数据库中的行。
我今天运行测试发送多个请求,并注意到我收到以下错误:
javax.persistence.OptimisticLockException
at org.jboss.resteasy.core.SynchronousDispatcher.handleApplicationException(SynchronousDispatcher.java:340) [resteasy-jaxrs-2.3.1.GA.jar:]
at org.jboss.resteasy.core.SynchronousDispatcher.handleException(SynchronousDispatcher.java:214) [resteasy-jaxrs-2.3.1.GA.jar:]
at org.jboss.resteasy.core.SynchronousDispatcher.handleInvokerException(SynchronousDispatcher.java:190) [resteasy-jaxrs-2.3.1.GA.jar:]
at org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:540) [resteasy-jaxrs-2.3.1.GA.jar:]
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:502) [resteasy-jaxrs-2.3.1.GA.jar:]
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:119) [resteasy-jaxrs-2.3.1.GA.jar:]
at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:208) [resteasy-jaxrs-2.3.1.GA.jar:]
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:55) [resteasy-jaxrs-2.3.1.GA.jar:]
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:50) [resteasy-jaxrs-2.3.1.GA.jar:]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.10.Final.jar:]
at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.1.0.Final.jar:7.1.0.Final]
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:154) [jboss-as-web-7.1.0.Final.jar:7.1.0.Final]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.10.Final.jar:]
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.10.Final.jar:]
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.10.Final.jar:]
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.10.Final.jar:]
at java.lang.Thread.run(Thread.java:619) [rt.jar:1.6.0_20]
为了能够解决上述问题,我需要了解以下内容:
如何在应用程序服务器上处理请求?是否每个请求都由自己的线程处理?
看到错误,我注意到它们被称为(http - 10.10.4.16-8080-1)和(http - 10.10.4.16-8080-7)。最后的数字是处理请求的线程号吗?
optimistiLockException表示在JPA / Hibernate发出提交之前尝试更新同一消息。如果我将相关代码放在同步块中,我如何确保请求的顺序是在同步块可用时处理它们的顺序?
有没有办法指示JPA / Hibernate在未提交更改时不尝试更新消息?
谢谢
答案 0 :(得分:2)
您可以使用的修复程序取决于您构建层的方式以及合并实体的来源。分离的实体是由弹簧数据绑定器组装,还是存储在Web会话中,还是从数据库中获取实体并在请求到达时对其进行更改?
如何在应用程序服务器上处理请求?是这样的 每个请求都由自己的线程处理?
它们由线程池处理。因此,每个请求都不会获得“它自己的”线程,但在任何给定时间,每个活动请求都由一个seoarate线程处理,是的。 (或者在队列中等待一个人释放。)
看到错误,我注意到他们被称为 (http - 10.10.4.16-8080-1)和(http - 10.10.4.16-8080-7)。是号码 最后处理请求的线程号?
整个事情是线程的名称。 Tomcat将数字放在最后以使它们成为唯一,但#除了由tomcat指定的任意顺序字符串之外没有任何特殊含义。
optimistiLockException表明有尝试 在JPA / Hibernate发出提交之前更新相同的消息。如果我放 同步块中的相关代码,我该如何确保 订单请求进来是他们处理时的顺序 同步块可用吗?
如果订单很重要,您需要在处理之前将它们放入某种队列中。同步不会对订单等待线程执行做出任何承诺。如果此过程是必须不失败的,请考虑在数据库中使用悲观锁,而不是在应用服务器上同步。使用该表的其他一些线程可能不会打扰sycnhing并导致异常。
有没有办法指示JPA / Hibernate不要尝试更新 如果有未提交的更改,请传递消息?
实际上,没有任何直接方法可以检查实体是否在内存缓存中的某个其他会话中有待处理的更新。 OptimisticLock检查是用于了解其他人是否进行了更改的机制。
答案 1 :(得分:0)
javax.persistence.OptimisticLockException
此异常通常在您的实体获得更新时发生,该实体具有自动生成的ID。尝试添加注释
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
如果这不起作用,请尝试
@OptimisticLock(excluded=true)
参见:Link