简体   繁体   English

线程未释放 spring 引导中的 jdbc 连接

[英]Thread not releasing jdbc connection in spring boot

We have a spring boot application whose starting point is an API. The API calls an interface say ITradeService which implements Callable.我们有一个 spring 启动应用程序,其起点是 API。API 调用一个接口 ITradeService,它实现了 Callable。 The ITradeService has a method service() which calls 7 methods in turn out of which the last three say method5() method6() and method7() are independent. ITradeService 有一个方法 service(),它依次调用 7 个方法,其中最后三个方法 method5() method6() 和 method7() 是独立的。

In the SIT,UAT environment for some reasons out of 4 nodes only one node is active and my project lead asked me to use 4 threads - 1 thread to execute the service method and other 3 threads to execute the above said 3 methods.在 SIT、UAT 环境中,由于某些原因,4 个节点中只有一个节点处于活动状态,我的项目负责人要求我使用 4 个线程 - 1 个线程执行服务方法,其他 3 个线程执行上述 3 个方法。

We have these three layers in our project我们的项目中有这三层

  • Controller(Rest API)控制器(休息API)
  • Service ITradeService服务 ITradeService
    TradeServiceImpl贸易服务实施
    Type1TradeServiceImpl Type2TradeServiceImpl Type3TradeServiceImpl Type1TradeServiceImpl Type2TradeServiceImpl Type3TradeServiceImpl
  • DAO CommonDao Type1Dao Type2Dao Type3Dao DAO CommonDao Type1Dao Type2Dao Type3Dao

We use JdbcTemplate in each of our DAO classes.我们在每个 DAO 类中使用 JdbcTemplate。

In our application.yaml we have configured the hikari database connection pool as 2在我们的 application.yaml 中,我们将 hikari 数据库连接池配置为 2

When i tried to execute the threads using ThreadPoolTaskExecutor for 4 requests the process is working as expected but when i send the 5th request it is saying当我尝试使用 ThreadPoolTaskExecutor 为 4 个请求执行线程时,进程按预期工作但是当我发送第 5 个请求时它说

CannotCreateTransactionException Could not open JDBC Connection for transaction CannotCreateTransactionException 无法打开 JDBC 事务连接

I understand that the 4 threads are holding the JDBC Connection.我知道 4 个线程持有 JDBC 连接。 I should make the threads release the JDBC connection and send it back to the hikari connection pool or i should close the threads upon task completion我应该让线程释放 JDBC 连接并将其发送回 hikari 连接池,或者我应该在任务完成后关闭线程

How should i do it in a spring specific way?我应该如何以 spring 特定方式进行操作?

It would be helpful to understand why you feel you need to run those three methods in parallel.这将有助于理解为什么您觉得需要并行运行这三种方法。

In any case, you can solve/mitigate the issue by:在任何情况下,您都可以通过以下方式解决/缓解问题:

  • setting the appropriate connectionTimeout , and maximumPoolSize to make sure either the pool autoscales to meet the application demand, or the additional threads do not timeout while waiting for the connection to be released, and/or设置适当的connectionTimeoutmaximumPoolSize以确保池自动缩放以满足应用程序需求,或者其他线程在等待释放连接时不会超时,和/或
  • making sure the time the connection is open during the execution of those three methods is as short as possible, eg the thread is not doing heavy calculations, file access etc. within a @Transactional method.确保在这三个方法执行期间连接打开的时间尽可能短,例如,线程不在@Transactional方法中进行繁重的计算、文件访问等。

Regarding the second bullet point, if you absolutely need the operations to be atomic, perhaps you could use optimistic locking (pull out the information you need and finish the unit of work there, do the heavylifting on a detached copy of the data, initiate another unit of work, see if the data changed in the meantime, and if so, retry the whole process, otherwise just update the data with your copy).关于第二个要点,如果你绝对需要原子操作,也许你可以使用乐观锁定(拉出你需要的信息并在那里完成工作单元,对数据的分离副本进行繁重工作,启动另一个工作单元,看看数据是否同时发生变化,如果是,重试整个过程,否则只用你的副本更新数据)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM