51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

在实验预约系统中,当多个用户同时预约同一设备时,如何保证数据一致性?请说明并发控制策略(如锁、乐观锁)以及实现方式。

绍兴理工学院实验员5 (其他技岗岗位)难度:中等

答案

1) 【一句话结论】:实验预约系统中,多个用户同时预约同一设备时,需通过**并发控制策略(如乐观锁或悲观锁)**保证数据一致性,核心是通过控制并发访问顺序或检查冲突,防止设备被重复预约,其中乐观锁适用于冲突概率低的场景,悲观锁适用于高冲突场景。

2) 【原理/概念讲解】:当多个用户同时请求预约同一设备时,数据库中该设备的“可用状态”和“预约记录”可能因并发操作产生冲突(比如用户A和用户B都看到设备可用,各自提交预约,导致设备被重复占用)。并发控制的目标是确保最终只有一个预约成功。

  • 悲观锁:预判冲突,在操作前加锁(如数据库行级锁),阻止其他事务修改该设备记录,直到当前事务完成。类比:图书馆借书时先占座位(锁),确保只有一个人能借,避免冲突。
  • 乐观锁:假设冲突概率低,先执行操作(如更新设备状态),再检查冲突(如版本号或时间戳)。若冲突则重试,否则成功。类比:先快速借书(操作),再检查是否被别人借走(检查版本),若被借走则返回错误。

3) 【对比与适用场景】:

策略定义特性使用场景注意点
悲观锁操作前加锁,阻止其他事务修改该设备记录严格控制并发,冲突时立即失败设备预约冲突概率高(如热门设备)可能导致死锁,性能受锁粒度影响
乐观锁操作后检查冲突,冲突时重试简单实现,冲突时重试设备预约冲突概率低(如冷门设备)需要版本号/时间戳字段,冲突时需重试逻辑

4) 【示例】(乐观锁实现):
假设设备表结构:

CREATE TABLE equipment (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    available BOOLEAN DEFAULT TRUE,
    version INT DEFAULT 0  -- 版本号,用于乐观锁
);

预约接口逻辑(伪代码):

def reserve_equipment(user_id, equipment_id):
    # 1. 查询设备当前状态和版本号
    equipment = db.query("SELECT available, version FROM equipment WHERE id = ?", equipment_id)
    if not equipment:
        return "设备不存在"
    # 2. 更新设备状态,检查版本号是否一致
    updated = db.update(
        "UPDATE equipment SET available = FALSE, version = version + 1 WHERE id = ? AND version = ?",
        equipment_id, equipment.version
    )
    if updated == 0:  # 版本号不一致,冲突
        return "设备已被其他用户预约,请重试"
    return "预约成功"

5) 【面试口播版答案】:
“在实验预约系统中,多个用户同时预约同一设备时,为保证数据一致性,我会采用乐观锁策略(冲突概率低时更高效)。具体实现是:在设备表中添加一个version字段(整数自增),预约时先查询设备当前状态和版本号,然后更新设备为“不可用”并递增版本号。若更新时发现版本号与查询时不同(说明已被其他事务修改),则返回冲突错误并让用户重试。这样既能保证数据一致性,又避免了悲观锁的锁竞争问题。”

6) 【追问清单】:

  • 追问1:如果设备预约冲突概率很高,应该用哪种策略?
    回答要点:若冲突概率高,应改用悲观锁(如数据库行级锁),通过加锁阻止其他事务修改设备记录,确保只有一个事务能成功预约。
  • 追问2:乐观锁的版本号丢失怎么办?
    回答要点:需确保版本号字段在更新时递增(如MySQL的自动递增),且查询时获取最新版本号,若版本号丢失(如数据库故障),可通过事务回滚或补偿机制处理。
  • 追问3:分布式环境下如何实现锁?
    回答要点:分布式环境下可使用分布式锁(如Redis的SETNX命令),通过原子操作确保只有一个节点能获取锁,避免单点故障。
  • 追问4:事务隔离级别如何选择?
    回答要点:对于设备预约,可选择读已提交(Read Committed)或可重复读(Repeatable Read),避免脏读或不可重复读,同时控制锁粒度。

7) 【常见坑/雷区】:

  • 乐观锁冲突处理:若未处理冲突(如直接更新失败后直接返回错误),可能导致用户重试后仍失败,需设计重试机制。
  • 锁粒度过大:悲观锁若加锁整个表,会导致所有设备都无法预约,影响系统可用性。
  • 分布式锁的单点故障:若使用Redis分布式锁,需考虑Redis故障时的锁释放问题(如设置超时时间)。
  • 事务隔离级别不当:若选择“读未提交”,可能导致用户看到设备可用但已被预约(脏读),影响用户体验。
  • 版本号字段类型:若版本号用字符串,递增时可能因长度限制导致冲突,应使用整数类型。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1