• 【mysql】只使用数据库DB如何实现--预定系统(古法)电影院座位预定


     1. 预定业务流程(以电影院座位预定)

     

    1. 用户看到电影院预定UI,其中有空位和预订的座位。
    2. 用户选择座位并向服务器发送请求。
    3. 座位是为一个时间段保留,在此期间,用户必须支付(比如10min)。
    4. 如果用户不付款,座位状态将被设置为空置,否则它将被标记为预订。

    2. 用悲观锁实现

    我们假设有一张表记录【放映厅】--【座位】维度的数据,还有一些其他列字段如movie_session、userId、seat_status(booked or vacant)等;

    case1:假设我选择一个座位,然后进入付款页面。此时,会话将获得一个锁,以便其他会话无法读取记录或对其进行更改。这种锁定被称为“独占锁定”。对于试图从表中访问锁定记录的任何其他用户的会话,必须等待表中特定记录的锁被释放。使用‘ FOR UPDATE’和 SELECT 查询来获取排他锁。

    • //A single transaction to book a tickets

      begin; // 事务开始

      seatsAvailable() -> Select * from booking where seat_number = ‘A1’ FOR UPDATE // 加排它锁&当前读

      bookTickets() -> update booking set customer_id = ‘101’ , seat_status = ‘booked’ where seat_number = ‘A1’; // 支付后更改 A1 row 数据状态

      commit; // 提交事务

    注意:另一种类型的锁定是“共享锁”,其中一个会话可以在该行已被其他会话获取锁时读取该行。但是,在第一个会话释放锁之前,它不能进行更新。使用‘ FORSHARE’和 SELECT 查询来获取共享锁。共享锁并不适用我们的分析场景;

    case2:多用户同时预订多个座位。一个用户选择A1至A4发起预定,与此同时,另一个用户选择的座位 A3至 A5发起预定。

    • //用户1 Transaction where user-1 books seats A1 to A4
      
      begin;
      
      seatsAvailable() -> Select * from booking where seat_number IN  (‘A1’,‘A2’, A3’, ‘A4’) FOR UPDATE  // 锁定数据行范围
      
      bookTickets() -> update booking set customer_id = ‘101’ , seat_status = ‘booked’ where seat_number IN  (‘A1’,‘A2’, A3’, ‘A4’) ; // 支付
      
      commit;
    • //用户2 A single transaction where user-2 tries to book seats A3 to A5
      
      begin;
      
      seatsAvailable() -> Select * from booking where seat_number IN  (‘A3’, A4’, ‘A5’) FOR UPDATE SKIP LOCKED; // 如果加SKIP LOCKED只会锁定A5行,否则获取锁失败返回
      
      bookTickets() -> update booking set customer_id = ‘102’ , seat_status = ‘booked’ where seat_number IN  (‘A3’, A4’, ‘A5’) // 
      
      commit;

    如果用户1优先获取了,A1-A4的行锁,在用户2则无法提交预定订单(因为A3,A4已经被加了排它锁),锁定失败,需要用户2重新选择其他座位;

    3. 小结

    • 以上只是为了说明数据库来做的话如何实现的;
    • 现实场景中加锁用的最多的还是分布式锁,如redis实现锁,来支持业务的高性能和扩展性。
    • 当然也可以使用数据乐观锁,如版本号机制来完成加锁的能力

  • 相关阅读:
    程序的链接
    TeleVis:基于NLP的新冠新闻舆情可视化项目
    数据结构与算法训练:第十八弹
    natapp内网穿透-将本地运行的程序/服务器通过公网IP供其它人访问
    【BLE】蓝牙技术的应用
    【Vue】响应式与数据劫持
    lua torch 官方学习教程
    多点DMALL × Apache Kyuubi:构建统一SQL Proxy探索实践
    【大咖说Ⅴ】陈文亮教授:基于语言理解的信息抽取研究
    前端入门的一些知识
  • 原文地址:https://blog.csdn.net/qfzhangwei/article/details/126560908