【问题标题】:Java - Distributed JPA Lock For ReservationJava - 用于保留的分布式 JPA 锁
【发布时间】:2019-07-19 10:14:18
【问题描述】:

我正在开发一个允许预订安排的遗留系统。该应用程序是无状态的 REST,旨在水平扩展。但是,数据库在所有实例之间共享。在我得到关于设计和规模的讲座之前,这不是我的 - 必须充分利用糟糕的情况(或代码库)。最近我们看到了一个重复预订的问题。我相信这是因为请求响应线程的性质。目前的流程是,接收请求,检查数据库是否有冲突的时间预留,如果没有,则插入。根据读取和插入之间的时间,两者都可能被插入。场景看起来像这样:

|------|-------|-------|
R1     C1      I1     RSP

-|--------|-------|---------|
R2       C2     I2   RSP

其中 R = 请求,C = DB 检查,I = 插入。

所以我相信我可以使用 @Synchronized 注释来强制对所有线程进行排序。问题在于有多个实例正在运行,因此无法运行整个实例。悲观或乐观的读写似乎并不适用,因为我们正在尝试进行读写组合,除非我完全误解了。有什么想法可以跨规模处理这个问题吗?宁愿通过表锁或类似的东西在java中处理它,而不是添加额外的服务(kafka,redis等)。

编辑: 数据库看起来像这样,在 dev 中使用 h2,在生产中使用 mysql。

 id |  start_time  | locationid | postingid | userid | durration
 --------------------------------------------------------------- 

【问题讨论】:

  • 冲突检查是什么样的?你用的是什么数据库?
  • "SELECT COUNT(*) WHERE time == ?", 数据库是 H2 和 MySQL
  • 这确实表明您可以简单地在 time 上添加一个唯一索引。您必须处理因重复插入而引发的异常。
  • 我需要在一系列复合字段上执行此操作。抱歉,我主要使用 sudo 代码。我不相信唯一索引是一个选项。已经考虑过了。
  • 如何替换检查然后插入,插入,提交,检查然后保留或删除? (提交是确保串行可见性所必需的)。

标签: java spring jpa concurrency


【解决方案1】:

从头开始实施这样的事情并不是火箭科学,但也许您可能想看看这个 GitHub 项目:https://github.com/alturkovic/distributed-lock

我既没有参与这个项目,也没有使用它,但它看起来很有希望。您只需要使用EnableJdbcDistributedLock 创建一个 Spring 配置:

@Configuration
@EnableJdbcDistributedLock
public class LockConfiguration {
}

并创建所需的数据库表:

create table lock (
  id int not null auto_increment primary key,
  lock_key varchar(255) unique,
  token varchar(255),
  expireAt timestamp,
);

一旦完成,您可以通过一个简单的注释(取自项目示例)在分布式环境中同步方法调用:

@JdbcLocked(expression = "#name")
public String sayHello(final String name) {
  return "Hello " + name + "!";
}

【讨论】:

  • 数据库应该在做这项工作,而不是应用程序。
  • @JonathanR,OP 要求基于分布式 JPA 的锁定机制,而这正是我提供的答案。也许 OP 不可能在数据库事务中执行所有涉及的调用?
【解决方案2】:

数据库应该处理这个问题。您可以:

您可以使用命令行 SQL 客户端在本地测试您的更改:打开两个并发事务,并尝试将 SELECTINSERT 交错的不同方式。

【讨论】:

    【解决方案3】:

    我认为合乎逻辑的事情是锁定该位置。如果我正确理解域,您正在为开始时间和持续时间给出的时间段预订特定位置(例如房间)?在这种情况下,您可能已经有一个位置实体。如果没有,您也许可以创建一个并添加一个匹配表。那么代码就很简单了:

    1. 使用 JPA 从请求中获取对位置的悲观锁定
    2. 检查数据库是否存在冲突
    3. 插入新的预留
    4. 提交

    表锁确实会损害可伸缩性,但锁定特定位置应该可以。

    【讨论】:

      猜你喜欢
      • 2021-01-20
      • 2011-07-24
      • 1970-01-01
      • 2017-06-05
      • 2010-10-30
      • 2022-05-13
      • 1970-01-01
      • 2012-09-10
      • 2018-05-05
      相关资源
      最近更新 更多