线程池中的Guice DAO提供程序 - 查询变为“在转换中空闲”

时间:2017-05-11 15:14:46

标签: java multithreading hibernate transactions guice

我使用Java 8,Hibernate 5.1.0.Final和Guice 4.1.0。

@Inject
private Provider<ExampleDAO> exampleDAOProvider;

public void test(){

    ExecutorService threadPool = Executors.newFixedThreadPool(10);

    for (int i = 0; i < 100; i++)
        threadPool.execute(new Runnable() {

            @Override
            public void run() {
                logger.info(exampleDAOProvider.find(1l));

            }
        });

    threadPool.shutdown();

}

每个test()方法执行将在pg_stat_activity中产生更多10(线程池大小)行。它们是简单的select * from查询,具有idle in transaction状态且永不消失。所以我达到hibernate.c3p0.max_size限制,我的应用程序停止使用数据库。

数据库模块:

public class ExampleModule extends PrivateModule {

    @Override
    public void configure() {

        install(new JpaPersistModule("example-persistence-unit").properties(jpaProperties()));

        bind(ExampleDAO.class).to(ExampleDAOImpl.class);

        expose(ExampleDAO.class);

        Key<PersistFilter> key = Key.get(PersistFilter.class, ExamplePersistenceUnit.class);
        bind(key).to(PersistFilter.class);
        expose(key);
    }
}

我已经尝试@Inject Provider<ExampleDAO> exampleDAOProvider进入任务类代码,但它没有改变任何东西。如果我@Inject exampleDAO,那么我会遇到并发问题(ConcurrentModificationException),因为它使用相同的EntityManager

如果我在没有多线程的情况下使用@Inject Provider<ExampleDAO> exampleDAOProvider或直接@Inject ExampleDAO exampleDAO,它可以很好地工作并且连接会被释放。

为什么会这样?如何在多线程代码中发布连接?

0 个答案:

没有答案