【发布时间】: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