【发布时间】:2023-01-07 17:25:05
【问题描述】:
语境:
- 带有 Spring JPA 和 MS SQL DB 的 Spring Boot 应用程序。
- 使用保险号的用户注册流程
- insuranceNumber 在 DB 中不是唯一的,但仅针对特定状态(PROSPECTIVE、PARTICIPANT)
- 服务中有一个重复检查来检查这个
REST Controller ->
RegistrationService (@Transactional)
- do duplicate check (select * from customer where status in (PROSPECTIVE,PARTICIPANT) and insuranceNumber = XYZ -> no results good)
- insert new customer to DB
问题:
- 如果经过测试,重复检查有效,但有时我有重复的 insuranceNumber 处于 PROSPECTIVE 状态
- 假设:
- 由于短时间内有多个 REST 请求,我有多个线程(假设有 3 个)
- 线程 1“重复检查”- 一切正常
- 线程 2“重复检查”- 一切正常(线程 1 尚未提交)
- 线程 1 插入 do DB,提交 TX
- 线程 2 插入 do DB,提交 TX ## 问题,现在具有相同保险号的客户处于相同状态
- 线程 3“重复检查”- 失败 - 正如预期的那样
可能的解决方案:
- 前端:防止这种多重请求。超出范围。我想从后端确定
- DB:在 DB 站点(数据库触发器)上创建一些东西以再次进行相同的重复检查。感觉不对,因为它重复了重复检查的逻辑。还会引发与已经在 Java 中引发的异常不同的异常
- Java 代码:带有同步方法的 RegistrationService。会减慢每个人的注册速度。对我来说,只允许一个保险号码进入注册方式就足够了。
在那里更多的想法?玩弄数据库的隔离级别? 如果一个线程已经进入了具有相同保险号的方法,则防止进入注册方法?
【问题讨论】:
标签: java spring spring-data-jpa