I am using Java 8, Hibernate 5.1.0.Final and 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(); }
Each execution of the test() method will create 10 (thread pool size) more in pg_stat_activity . These are simple select * from queries that have an idle in transaction state and never disappear. Therefore, I reach the limit of hibernate.c3p0.max_size , and my application stops working with the database.
Database Module:
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); } }
I tried @Inject Provider<ExampleDAO> exampleDAOProvider to enter the task class code, but didn't change anything. If I @Inject exampleDAO , then I am facing concurrency ( ConcurrentModificationException ) problems because it uses the same EntityManager .
If I use @Inject Provider<ExampleDAO> exampleDAOProvider or direct @Inject ExampleDAO exampleDAO without multithreading, it works well and the connections are released.
Why is this happening? How to get connections released in multi-threaded code?
source share