为了账号安全,请及时绑定邮箱和手机立即绑定

JPA 存储库和阻塞 I/O

JPA 存储库和阻塞 I/O

MMTTMM 2022-12-15 14:52:28
我遇到一个问题,在使用 JpaRepository 写入数据库后,我需要在单独的线程上执行几个慢速 HTTP 请求。问题是doActualJob()在等待一系列期货解决时的阻塞。这似乎可以防止底层 Hibernate 会话关闭,从而导致应用程序很快用完连接。如何编写此函数,以便在执行阻塞 I/O 时数据库连接不保持打开状态?甚至可以使用 JpaRepositories,还是我需要使用像 EntityManager/SessionFactory 这样的较低级别的 API?@Serviceclass SomeJobRunner {    private final SomeJobRepository mSomeJobRepository; //extends JpaRepository    @AutoWired    public SomeJobRunner(final SomeJobRepository someJobRepository) {        mSomeJobRepository = someJobRepository;    }    @Async    public void doSlowJob(final long someJobId) {        SomeJob someJob = mSomeJobRepository.findOne(someJobId);        someJob.setJobStarted(Instant.now());        mSomeJobRepository.saveAndFlush(someJob);        doActualjob(); // Synchronous job doing several requests using Unirest in series        someJob = mSomeJobRepository.findOne(someJobId);        someJob.setJobEnded(Instant.now());        mSomeJobRepository.saveAndFlush(someJob);}
查看完整描述

2 回答

?
慕斯王

TA贡献1864条经验 获得超2个赞

嗯——非阻塞数据库 IO 在 Java/JDBC 世界中以标准方式是不可能的。简而言之——你的 Spring 数据存储库最终将使用 JPA ORM 实现(比如 Hibernate),而 JPA ORM 实现又将使用 JDBC 与之交互本质上是阻塞的数据库。Oracle(异步数据库访问 API )目前正在做这方面的工作,以提供与 JDBC 类似但非阻塞的 API。他们打算将此作为标准提出。Spring 人员在这方面也有一项令人兴奋的并行工作,即R2DBC – 反应式关系数据库连接。他们实际上也将其与 Spring 数据集成(链接) 这样可以帮助您集成到您的解决方案中。可以在此处找到 Spring 的一个很好的教程。

查看完整回答
反对 回复 2022-12-15
?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

我建议使用单独的JTA 事务写入数据库。这样做,定义一个像这样的方法


@Transactional(Transactional.TxType.REQUIRES_NEW)

public void saveJobStart(final long someJobId) {

    SomeJob someJob = mSomeJobRepository.findOne(someJobId);

    someJob.setJobStarted(Instant.now());

    mSomeJobRepository.saveAndFlush(someJob);

}

当然不完全一样。如果doActualjob()失败,在您的情况下,数据库将不会保留开始日期。在我的提议中,它会坚持下去。作为补偿,您需要在新事务中删除doSlowJobcatch中的bloc 中的开始日期,然后重新处理异常。 throw


查看完整回答
反对 回复 2022-12-15
  • 2 回答
  • 0 关注
  • 71 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信