代码之家  ›  专栏  ›  技术社区  ›  Sunny

当激发多个线程以获取数据时,查询无法获取结果

  •  -2
  • Sunny  · 技术社区  · 6 年前

    我有一个Spring Bug应用程序,我使用Java并发包的可调用性在PASGREST表上进行5 dB查询。

    我正在使用的“用户”表非常小,只有6个条目,但应用程序仍然需要40秒以上的时间来显示数据,并在40秒后给出异常。

    数据服务impl.java

    @Service
    public class DataServiceImpl {
        /*@Autowired
        private EntityManagerFactory emf;*/
    
        @Autowired
        private EntityManager entityManager;
    
        public List<Object> showUser(int firstParam, int secondParam) {
            //EntityManager entityManager = emf.createEntityManager();
            String sql = "select * from sunny.user where id between ?1 and ?2";
            Query query = entityManager.createNativeQuery(sql);
            query.setParameter(1, firstParam);
            query.setParameter(2, secondParam);
            return query.getResultList();
        }
    }
    

    用户服务.java

    @Service
    public class UserService {
    
        @Autowired
        private DataServiceImpl dataServiceImpl;
    
        public List<Object> callUser() throws InterruptedException, ExecutionException {
            int startParam = 1;
            int endParam = 6;
            List<Future<List<Object>>> futures = new ArrayList<>();
            ExecutorService executorService = Executors.newCachedThreadPool();
            List<Object> b = null;
            for (int i = startParam; i < 6; i++) {
                if (i == 1)
                    endParam = startParam + 1;
                else {
                    startParam += 1;
                    endParam += 1;
                }
                Callable<List<Object>> callable = new ProcessingData(startParam, endParam);
                futures.add(executorService.submit(callable));
            }
            executorService.awaitTermination(40, TimeUnit.SECONDS);
            int i = 0;
            for (Future<List<Object>> f : futures) {
                if (i == 0) {
                    b = new ArrayList<>(f.get());
                } else {
                    b.add(f.get());
                }
                i++;
            }
            return b;
        }
    
        private class ProcessingData implements Callable<List<Object>> {
            private int firstParam;
            private int secondParam;
            /*
             * @Autowired private DataServiceImpl dataServiceImpl;
             */
    
            public ProcessingData(int firstParam, int secondParam) {
                super();
                this.firstParam = firstParam;
                this.secondParam = secondParam;
            }
    
            @Override
            public List<Object> call() throws Exception {
                return dataServiceImpl.showUser(firstParam, secondParam);
           }
        }
    }
    

    您可以在这里找到整个代码- Git Code Here

    有人能告诉我我哪里做错了吗? 40秒后出现异常:

    1  Iftekhar
    2  Sunny
    2018-05-27 13:29:19.096 ERROR 9836 --- [nio-8085-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: java.util.ArrayList cannot be cast to [Ljava.lang.Object;] with root cause
    
    java.lang.ClassCastException: java.util.ArrayList cannot be cast to [Ljava.lang.Object;
        at com.example.controller.UserController.showUser(UserController.java:24) ~[classes/:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_144]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_144]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_144]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_144]
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) ~[spring-webmvc-5.0.6.RELEASE.jar:5.0.6.RELEASE]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.31.jar:8.5.31]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
    

    正如您所看到的,我只获取前2行的数据以及之后的异常,因为其他查询无法在40秒内完成,所以它们会抛出异常,因为它们返回的值为空。

    激发的查询:

    Hibernate: select * from sunny.user where id between ? and ?
    Hibernate: select * from sunny.user where id between ? and ?
    Hibernate: select * from sunny.user where id between ? and ?
    Hibernate: select * from sunny.user where id between ? and ?
    Hibernate: select * from sunny.user where id between ? and ?
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Antoniossss    6 年前
    executorService.awaitTermination(40, TimeUnit.SECONDS);
    

    这将阻塞40秒,但为了使其正常工作,您必须致电 executorService.shutdown(); 第一。所以试试看

      executorService.shutdown();
      executorService.awaitTermination(40, TimeUnit.SECONDS);
    

    而且, awaitTermination 退货 boolean 这表示是否达到了超时(真=任务正常完成,假=超时)或任务在指定时间之前完成-您似乎忽略了该值,而我将以不同的方式处理这两种情况。