Spring 引导 JPA 和 HikariCP 保持活动连接

Spring Boot JPA and HikariCP maintaining active connections

简介

有没有办法确保与数据库的连接return进入池?

不简短:

数据流:

  1. 我有一些较长的 运行 任务可以大量突发发送到服务器。
  2. 每个请求都记录在开始提交的数据库中。然后发送该请求进行处理。
  3. 如果失败或成功,则在任务完成后记录请求。

问题是在漫长的运行任务中一路记录提交后,连接池使用了一个"active"连接。如果爆发足够大,这可能会耗尽我拥有的任何大小的池。

我正在使用具有以下结构的 spring 启动:

  1. 控制器 - 在“/”处响应并"service"自动装配。
  2. 服务 - 包含与数据库交互的所有 JPA 存储库和@Transactional 方法。

当每次从控制器发出第一个服务方法调用时,它都会打开一个活动连接,并且直到控制器方法 returns 才释放它。

那么,有没有办法在每个服务方法之后return连接到池?

这里是服务 class 一共:

@Service
@Slf4j
class SubmissionService {

@Autowired
CompanyRepository companyRepository;

@Autowired
SubmissionRepository submissionRepository;

@Autowired
FailureRepository failureRepository;

@Autowired
DataSource dataSource

@Transactional(readOnly = true)
public Long getCompany(String apiToken){
    if(!apiToken){
        return null
    }
    return companyRepository.findByApiToken(apiToken)?.id
}

@Transactional
public void successSubmission(Long id) {
    log.debug("updating submission ${id} to success")
    def submissionInstance = submissionRepository.findOne(id)
    submissionInstance.message = "successfully analyzed."
    submissionInstance.success = true
    submissionRepository.save(submissionInstance)
}

@Transactional
public long createSubmission(Map properties) {
    log.debug("creating submission ${properties}")
    dataSource.pool.logPoolState()
    def submissionInstance = new Submission()
    for (key in properties.keySet()) {
        if(submissionInstance.hasProperty(key)){
            submissionInstance."${key}" = properties.get(key)
        }
    }
    submissionInstance.company = companyRepository.findOne(properties.companyId)
    submissionRepository.save(submissionInstance)
    return submissionInstance.id
}

@Transactional
public Long failureSubmission(Exception e, Object analysis, Long submissionId){
    //Track the failures
    log.debug("updating submission ${submissionId} to failure")
    def submissionInstance
    if (submissionId) {
        submissionInstance = submissionRepository.findOne(submissionId)
        submissionRepository.save(submissionInstance)
    }

    def failureInstance = new Failure(submission: submissionInstance, submittedJson: JsonOutput.toJson(analysis), errorMessage: e.message)

    failureRepository.save(failureInstance)

    return failureInstance.id
  }
}

事实证明@M.Deinum走对了路。 Spring 如果应用程序 属性 spring.jpa.open_in_view 设置为 true(默认情况下),Boot JPA 会自动打开 "OpenEntityManagerInViewFilter"。我在 JPA Configuration Source 中找到了这个。

将此设置为 false 后,数据库会话没有保持,我的问题就消失了。