当前位置: 首页 > 知识库问答 >
问题:

如何条件数据库插入操作在JavaSpring锁?

楚宪
2023-03-14

我正在尝试对数据库执行条件插入操作(假设为SQLite)。我的目标是确保数据一致性。

假设我们正在做一个预约计划。

所以我们有一个这样的约会表:

>

  • 编号

    个人的

    appointment_date

    但是我们有一个重要的规则,一个人在同一天的约会不能超过3次。

    通常,我们从数据库中查询此人当天有多少约会。然后我们决定是否插入。对吧?

    但是,假设我们有一个获得大量流量的API。假设两个类似的交易在同一毫秒内开始,并且以某种方式同一个人获得了第4次约会。这是我们不想要的。

    我了解到为了防止这种情况,应该在数据库中应用锁操作。但是我无法理解应用哪种锁类型。我们知道悲观锁会发生死锁。当然,我们不希望出现这种情况。

    我的问题是,在Java Spring Boot中我应该做什么来防止这种情况?

    实体:

    @Entity
    @AllArgsConstructor
    @NoArgsConstructor
    @Getter
    @Setter
    public class Appointment {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    
        private String person;
    
        private Date appointment_date;
    
    }
    

    服务:

    @Service
    public class AppointmentService {
        @Autowired
        private AppointmentRepository appointmentRepository;
    
        public Appointment saveAppointment(Appointment appointment) {
            return appointmentRepository.save(appointment);
        }
    }
    

    存储库:

    @Repository
    public interface AppointmentRepository extends JpaRepository<Appointment, Long> {
    }
    

    控制器:

    @RestController
    public class AppointmentController {
    
        @Autowired
        private AppointmentService appointmentService;
    
        @PostMapping(“/store”)
        public Appointment store(@RequestBody Appointment appointment) {
            return appointmentService.saveAppointment(appointment);
        }
    }
    

    非常感谢您的关注:)

  • 共有1个答案

    韦德厚
    2023-03-14

    假设您可以更改表模式。在这种情况下,约会聚合将包括

    • id
    • 人ID
    • 预约日期
    • 版本
    • 创建日期

    您可以通过在实体中添加@Version注释和表中添加列来使用乐观锁。

    伪代码

    @Entity
    public class Appointment {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    
        @OneToOne
        private String personId;
    
        @ElementCollection
        private List<Date> appointmentDates = new ArrayList<>();
    
        @Version private Long version;
    
        private Instant createdDate;
    
    
        public static Appointment create(Appointment appointment) {
            // code that creates a new appointment
        }
    
        public Appointment addAppointment() {
            // code that updates your appointment
        }
    
    }
    

    @版本注释

    在您的服务类中,您可以创建一个新的约会伪代码

    var appointment = Appointment.create(newAppointment);
    repository.save(appointment);
    

    或者更新伪代码

    var appointmentToUpdate = repository.findById(appointmentId);
    // validation for appointment count and date
    if (createdDate.isToday() && appointmentToUpdate.getAppointmentDates().size() >= 3)
      // exception
    var updatedAppointment = appointmentToUpdate.addAppointment();
    repository.save(updatedAppointment);
    

    它将抛出 OptimisticLockException,以防另一个线程修改此实体。

     类似资料:
    • 问题内容: 我想使用Web服务在远程Web服务器上的MYSQL数据库中插入文件。 我的问题是:什么类型的表列(例如varchar等)将存储文件?对于文件,insert语句会有所不同吗? 问题答案: BLOB数据类型最适合存储文件。 请参阅:如何使用PHP将.pdf文件作为BLOB存储到MySQL中? MySQL BLOB参考手册有一些有趣的注释

    • 问题内容: 我想在我的MySQL数据库中插入整数188和90,但以下代码不起作用: 为什么不起作用? 问题答案: 编辑 为我工作: 在MySQL表;

    • 我想发出一个将数据插入数据库的请求。该表有4列:ID_DOCUMENT(PK)、ID_TASK、DESCRIPTION、FILEPATH 当我运行我的测试时,我得到了这个错误:由:org.hibernate.hql.ast.querysyntaxException引起的:预期打开,在第1行第32列附近发现'c'[insert into TaskDocumentEntity c(c.IDTask,c

    • 本文向大家介绍node.js如何操作MySQL数据库,包括了node.js如何操作MySQL数据库的使用技巧和注意事项,需要的朋友参考一下 MySQL数据库作为最流行的开源数据库。基本上是每个web开发者必须要掌握的数据库程序之一了。 基本使用 node.js上,最受欢迎的mysql包就是mysql模块。 然后在js脚本里面直接引用进来 配置mysql的数据库连接。 这样就拿到了一个连接。 然后就

    • 我有一个电子邮件订阅我的网站,我想插入到我的Wordpress数据库,所以我可以导出电子邮件列表。我已经创建了表wp_email_subscription,其中包含4个字段ID、名称、电子邮件和创建日期。对此将进行什么查询?有没有wordpress数据库脚本可以使用?

    • 数据库的操作是每个phpweb框架的核心功能,我们提供数据库数据库的标准调用模式为: 你可以执行严格模式,也就是左边的那条线,Controller->Service->Dao->Model->DB,也可以走简单模式 Controller->Model->DB。个人根据自己的需求,走标准麻烦些(几乎所有的机构和系统都是这样^_^), 但是扩展性会好些,但是使用简单模式开发效率就会高些,性能会好些,但