Spring 引导 JPA 和 HikariCP 保持活动连接
Spring Boot JPA and HikariCP maintaining active connections
简介:
有没有办法确保与数据库的连接return进入池?
不简短:
数据流:
- 我有一些较长的 运行 任务可以大量突发发送到服务器。
- 每个请求都记录在开始提交的数据库中。然后发送该请求进行处理。
- 如果失败或成功,则在任务完成后记录请求。
问题是在漫长的运行任务中一路记录提交后,连接池使用了一个"active"连接。如果爆发足够大,这可能会耗尽我拥有的任何大小的池。
我正在使用具有以下结构的 spring 启动:
- 控制器 - 在“/”处响应并"service"自动装配。
- 服务 - 包含与数据库交互的所有 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 后,数据库会话没有保持,我的问题就消失了。
简介:
有没有办法确保与数据库的连接return进入池?
不简短:
数据流:
- 我有一些较长的 运行 任务可以大量突发发送到服务器。
- 每个请求都记录在开始提交的数据库中。然后发送该请求进行处理。
- 如果失败或成功,则在任务完成后记录请求。
问题是在漫长的运行任务中一路记录提交后,连接池使用了一个"active"连接。如果爆发足够大,这可能会耗尽我拥有的任何大小的池。
我正在使用具有以下结构的 spring 启动:
- 控制器 - 在“/”处响应并"service"自动装配。
- 服务 - 包含与数据库交互的所有 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 后,数据库会话没有保持,我的问题就消失了。