【问题标题】:Spring Boot JPA and HikariCP maintaining active connectionsSpring Boot JPA 和 HikariCP 维护活动连接
【发布时间】:2015-09-19 01:21:56
【问题描述】:

简介

有没有办法确保与数据库的连接返回到池中?

不简短:

数据流:

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

问题是,在长时间运行的任务中一直记录提交后,连接池使用“活动”连接。如果爆发足够大,这可能会耗尽我拥有的任何大小的池。

我正在使用具有以下结构的弹簧靴:

  1. 控制器 - 响应“/”并自动连接“服务”。
  2. Service - 包含所有 JPA 存储库和 @Transactional 方法以与数据库交互。

当每次从控制器调用第一个服务方法时,它都会打开一个活动连接,并且在控制器方法返回之前不会释放它。

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

这里是服务类的总和:

@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
  }
}

【问题讨论】:

  • 为什么你认为一个控制器方法调用的连接被检索到并且只有在控制器方法返回时才返回到池中?事务结束时,连接会返回到池中。
  • 嗯,这取决于是否有OpenEntityManagerInViewFilter(或拦截器),为传入的请求打开和维护会话和连接。
  • @JBNizet 来自我的调试,似乎在它发布时。我能够记录池的活动连接,并且在 Transactional 方法之后没有返回连接。
  • @M.Deinum 我对你的评论投了赞成票,但错误地删除了它,我要让其他人再次投票。

标签: spring spring-boot spring-data-jpa hikaricp


【解决方案1】:

事实证明@M.Deinum 走上了正确的道路。如果应用程序属性spring.jpa.open_in_view 设置为 true,Spring Boot JPA 会自动打开“OpenEntityManagerInViewFilter”,这是默认设置。我在JPA Configuration Source 中找到了这个。

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

【讨论】:

    猜你喜欢
    • 2019-10-10
    • 1970-01-01
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    • 2019-12-16
    相关资源
    最近更新 更多