如何使用 Spring Boot 设置 Spring JDBC 连接池?

Posted

技术标签:

【中文标题】如何使用 Spring Boot 设置 Spring JDBC 连接池?【英文标题】:How to setup Spring JDBC Connection Pooling with Spring Boot? 【发布时间】:2019-03-15 22:55:09 【问题描述】:

我正在使用带有 Spring JDBC 的 Spring Boot 1.5.4。

有一个使用 Spring JDBC 的 Spring Boot 微服务在尝试执行 HTTP PUT(在一群用户尝试执行 HTTP PUT 之后)时会出现以下问题,该问题会渗透到这个 Spring JDBC 调用:

2018-10-10 19:40:02 [http-nio-8081-exec-4] ERROR c.v.r.RepositoryImpl - Problem in updateData() method: 
"org.springframework.dao.DataAccessResourceFailureException: PreparedStatementCallback; SQL [select a.user_id,b.user_id, from user a join user_profile b where a.user_id=b.user_id and a.date=?;]; No operations allowed after connection closed.; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
    at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:79)
    at java.lang.Thread.run(Thread.java:748)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:377)
    at com.mysql.jdbc.Util.getInstance(Util.java:360)
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 28,915,589 milliseconds ago.  The last packet sent successfully to the server was 9 milliseconds ago.
    at com.myapp.repository.RepositoryImpl.updateData(RepositoryImpl.java:74)
    at com.myapp.repository.RepositoryImpl$$FastClassBySpringCGLIB$$1be9dd8e.invoke(<generated>)
    ... 52 common frames omitted
Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2914)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3337)
    ... 83 common frames omitted

pom.xml:

<artifactId>MyService</artifactId>
<packaging>jar</packaging>
<version>1.0</version>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.4.RELEASE</version>
</parent>

<properties>
    <java.version>1.7</java.version>
</properties>   

<dependencies>
    <!-- Spring -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.33</version>
    </dependency>
</dependencies>

我猜我需要设置一个 JDBC 连接池...

在我的 application.properties 设置中,(我有两个不同的数据库 - 一个本地数据库和一个远程数据库,它与远程数据库失去连接;数据库 2):

# Local
spring.datasource.database1.url=jdbc:mysql://localhost/database1?zeroDateTimeBehavior=convertToNull
spring.datasource.database1.username=root
spring.datasource.database1.password=ret2my
spring.datasource.database1.driverClassName=com.mysql.jdbc.Driver

# Remote
spring.datasource.database2.url=jdbc:mysql://read-replica-database-production.cranmichpmc.us-west-2.rds.amazonaws.com/database2?zeroDateTimeBehavior=convertToNull
spring.datasource.database2.username=root
spring.datasource.database2.password=ret2a$$
spring.datasource.database2.driverClassName=com.mysql.jdbc.Driver

我应该为第二个数据库添加这个:

spring.datasource.database2.hikari.maximum-pool-size=10
spring.datasource.database2.hikari.connection-timeout=60000

我应该考虑其他有用的参数吗?

【问题讨论】:

【参考方案1】:
spring.datasource.url=jdbc:mysql://10.168.143.140:3306/database_name
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.hikari.maximum-pool-size=4

更多详细信息请见: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html

【讨论】:

谢谢 Ajay,我在用 hikari 吗?应该高于 4 吗? 您可以使用 tomcat 或 hikari。 max-pool 取决于您的应用程序要求和可用的数据库连接数。 有时会发生其他程序可能会保留数据库连接并阻止您的程序访问数据库连接资源。我建议您检查 db 上的活动客户端连接

以上是关于如何使用 Spring Boot 设置 Spring JDBC 连接池?的主要内容,如果未能解决你的问题,请参考以下文章

使用“spring-boot-starter-oauth2-resource-server”设置资源服务器时,不会自动注入 JwtDecoder bean

如何结合 Spring Boot HornetQAutoConfiguration 和 CachingConnectionFactory?

如何在具有 JDBC 安全性的 Spring Boot 中使用 Flyway?

找不到带有spring boot的html页面

spring-boot入门

尝试运行 Spring Boot 应用程序时无法部署到 docker