java - Tapestry Hibernate session 超出 ExecutorService 固定线程池后关闭

标签 java multithreading hibernate tapestry

我是一个 Tapestry-hibernate 用户,我遇到了一个问题:一旦超过 Executors.newFixedThreadPool(1);,我的 session 就会保持关闭状态;

我有以下代码,它将完美地适用于第一个线程,而其余线程则经历关闭的 session 。如果我将线程池增加到 10,所有线程都将正常运行。一旦超过固定线程池,我就会收到 session 关闭异常。我不知道如何打开它,因为它是由 Tapestry-Hibernate 管理的。如果我使用 newCachedThreadPool,一切都会完美运行。有人知道这里会发生什么吗?

public void setupRender() {
        ExecutorService executorService = Executors.newFixedThreadPool(1);

        final ConcurrentHashMap<String, Computer> map = new ConcurrentHashMap<>();
        final String key = "myKey";

        final Date date = new Date();

        List<Future> futures = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            final int thread = i;

            Future future = executorService.submit(new Callable() {

                @Override
                public String call() {
                    try {
                        Computer computer = new Computer("Test Computer thread");
                        computer = getComputer(map, key, key, computer);

                        Monitor monitor = new Monitor();
                        monitor.setComputer(computer);

                        session.save(monitor);
                        session.flush();
                        System.out.println("thread " + thread);
                        try {
                            sessionManager.commit();
                        } catch (HibernateException  ex) {
                            sessionManager.abort();
                        } finally {
                            session.close();
                        }
                    } catch (Exception ex) {
                        System.out.println("ex " + ex);
                    }
                    System.out.println( new Date().getTime() - date.getTime());
                    return "completed";
                }                

            });
            futures.add(future);
        }

        for(Future future : futures) {
            try {
                System.out.println(future.get());
            } catch (InterruptedException | ExecutionException ex) {
                Logger.getLogger(MultiThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public synchronized Computer getComputer(ConcurrentHashMap<String, Computer> map, String key, String thread, Computer computer) {
        if (map.putIfAbsent(key, computer) == null) {
            session.save(computer);
        } else {
            computer = map.get(key);
        }
        return computer;
    }

最佳答案

我之前已经告诉过你了......你必须使用ParallelExecutor或调用PerThreadManager.cleanup()。您需要了解 Tapestry-hibernate 有 PerThread如果您在正常请求/响应(或 ParallelExecutor)之外使用它们,则必须清理这些范围内的服务。

我也不认为您应该调用session.close()。你应该模仿CommitAfterWorker .

它可能看起来像:

@Inject PerThreadManager perThreadManager;
@Inject HibernateSessionManager sessionManager; // this is a proxy to a per-thread value
@Inject Session session; // this is a proxy to a per-thread value

public void someMethod() {    
    ExecutorService executorService = ...;
    executorService.submit(new Callable() {
        public String call() {
            try {
                Monitor monitor = ...
                session.save(monitor);
                session.flush(); // optional
                sessionManager.commit();
            } catch (Exception ex) {
                sessionManager.abort();
            } finally {
                // this allows Session and HibernateSessionManager to
                // clean up after themselves
                perThreadManager.cleanup();
            }
            return ...
        }                
    });
}

如果您选择使用ParallelExecutor (和 Invokable )而不是 Executors.newFixedThreadPool(1) 您可以删除对 PerThreadManager 的引用,因为它会自动清理线程。

关于java - Tapestry Hibernate session 超出 ExecutorService 固定线程池后关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19988480/

相关文章:

java - 如何在java中使用DecimalFormat?

java - 使@Embeddable 类可选?

自减/自增运算符的Java表达式解释规则

java - 分组对象java 8

java - 如何在 Maven 模块之间共享 protobuf 文件?

java - 如何在没有 volatile 的情况下打破双重检查锁定

c# - 客户端/服务器 Winforms C#

java - 有没有更优雅的方式来启动基于列表的线程?

java - Spring STS DB 与 Jpa 的连接

java - 嵌套 session /事务中的 Transaction.rollback 会发生什么?