Spring Boot DB 连接释放方式

问题描述

Spring Boot 有没有办法控制数据库连接释放策略?类似于 Hibernate 的 ConnectionReleaseMode

我的测试代码大致如下:

  1. 插入查询
  2. HTTP 调用
  3. 更新查询

INSERT 和 UPDATE 查询是它们自己在存储库 bean 中的方法(扩展 CrudRepository,或作为 Mybatis @Mapper)。 HTTP 调用在它自己的 bean 中。

现在我的服务 bean 是我试验不同 @Transactional 设置的地方,因为我的最终目标是在单个事务中执行这三个步骤。

问题是,HTTP 调用可能需要数百毫秒,而 Spring 在此期间保持数据库连接。这很快会导致连接池为空,而连接本身处于空闲状态。

我使用 spring-boot-starter-data-jpamybatis-spring-boot-starter认配置进行了相同的实验。

让我更接近目标的唯一一件事是为 spring.jpa.open-in-view=false 设置 data-jpa,这将在根本不使用 @Transactional 或传播设置为 { 的情况下释放数据库连接{1}}。但是,如果全部都包裹在 transactin 中,它就不起作用。

我感觉我错过了 Spring 中事务概念的一些重要部分。尽管 Spring reference docs mentions release mode 仅与 JTA 事务管理器 + JEE 容器 + Hibernate 相关。

解决方法

事务绑定到连接/会话,因此您无法在事务中间释放连接。您必须完成事务才能关闭/释放连接。请记住,事务可能随时中止,并且由于 HTTP 调用不是事务的“一部分”,而只是在事务进行时运行,因此它不会帮助您在 HTTP 期间保持事务打开通话正在运行。我建议您采用以下解决方案之一:

  1. 如果 HTTP 调用达到超时,则使用断路器取消 HTTP 调用,以设置连接/事务可以打开/保持多长时间的上限
  2. 在事务之前或之后将 HTTP 调用移出事务
  3. 使用两个数据库事务

请注意,您可以使用事务性作业调度程序在第一个 TX 中调度作业。然后,作业可以使用至少一次语义尝试调用 HTTP 调用,然后继续第二个事务,或者在出现故障时进行一些补偿。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...