保持 JPA EntityManager 打开 - 连接池
Keeping JPA EntityManager open - Connection Pooling
在我们开发的一个 RESTful 网络服务中(Spring MVC - Rest),我们对数据库进行了大约 50 次调用。这大约需要一分钟才能完成。我们可以看到,每次调用后,JPA 实体管理器都会关闭并创建一个新的实体管理器,如下面的日志所示
DEBUG o.s.o.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
17:18:16.399 [http-bio-8080-exec-5] DEBUG o.s.o.j.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler - Creating new EntityManager for shared EntityManager invocation
我们怀疑这需要时间,因为查询在其自身执行时花费的时间最少。我们如何确保 JPA 连接始终保持打开状态?请注意,这是一个 GET 调用,我们没有进行任何更新。我们如何实现连接池? JPA连接的closing\opening这么贵吗?
这是我们以编程方式声明 EntityManager (ApplicationConfiguration) 的地方
LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
entityManagerFactory.setDataSource(dataSource());
entityManagerFactory.setPersistenceProviderClass(HibernatePersistence.class);
entityManagerFactory.setPackagesToScan("com.skyteam.api.flightstatus.domain.persistence");
Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.show_sql", "true");properties.put("hibernate.show_sql", "true");
我尝试了以下使用 hibernate 的 c3p0 进行连接池的方法,但没有帮助。
properties.put("hibernate.c3p0.min_size", "5");
properties.put("hibernate.c3p0.max_size", "20");
properties.put("hibernate.c3p0.timeout", "300");
properties.put("hibernate.c3p0.max_statements", "50");
properties.put("hibernate.c3p0.idle_test_period.timeout", "3000");
有什么帮助吗? (注意 - 之前看起来相似的问题没有帮助)
您似乎是在方法 dataSource()
中创建数据源。
我相信,你有两个选择:
- 将该数据源包装到
ComboPooledDataSource
中。它也是
实现 javax.sql.DataSource
接口并将池化添加到
数据库连接。
不要显式创建数据源,而是让 JPA 创建它。
像这样:
properites.put("javax.persistence.jdbc.driver","...");
properites.put("javax.persistence.jdbc.url","...");
properites.put("javax.persistence.jdbc.user","...");
properites.put("javax.persistence.jdbc.password","...");
在我们开发的一个 RESTful 网络服务中(Spring MVC - Rest),我们对数据库进行了大约 50 次调用。这大约需要一分钟才能完成。我们可以看到,每次调用后,JPA 实体管理器都会关闭并创建一个新的实体管理器,如下面的日志所示
DEBUG o.s.o.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
17:18:16.399 [http-bio-8080-exec-5] DEBUG o.s.o.j.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler - Creating new EntityManager for shared EntityManager invocation
我们怀疑这需要时间,因为查询在其自身执行时花费的时间最少。我们如何确保 JPA 连接始终保持打开状态?请注意,这是一个 GET 调用,我们没有进行任何更新。我们如何实现连接池? JPA连接的closing\opening这么贵吗?
这是我们以编程方式声明 EntityManager (ApplicationConfiguration) 的地方
LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
entityManagerFactory.setDataSource(dataSource());
entityManagerFactory.setPersistenceProviderClass(HibernatePersistence.class);
entityManagerFactory.setPackagesToScan("com.skyteam.api.flightstatus.domain.persistence");
Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.show_sql", "true");properties.put("hibernate.show_sql", "true");
我尝试了以下使用 hibernate 的 c3p0 进行连接池的方法,但没有帮助。
properties.put("hibernate.c3p0.min_size", "5");
properties.put("hibernate.c3p0.max_size", "20");
properties.put("hibernate.c3p0.timeout", "300");
properties.put("hibernate.c3p0.max_statements", "50");
properties.put("hibernate.c3p0.idle_test_period.timeout", "3000");
有什么帮助吗? (注意 - 之前看起来相似的问题没有帮助)
您似乎是在方法 dataSource()
中创建数据源。
我相信,你有两个选择:
- 将该数据源包装到
ComboPooledDataSource
中。它也是 实现javax.sql.DataSource
接口并将池化添加到 数据库连接。 不要显式创建数据源,而是让 JPA 创建它。 像这样:
properites.put("javax.persistence.jdbc.driver","..."); properites.put("javax.persistence.jdbc.url","..."); properites.put("javax.persistence.jdbc.user","..."); properites.put("javax.persistence.jdbc.password","...");