面试题答案
一键面试锁粒度选择策略
- 按业务操作粒度:
- 粗粒度:以整个业务流程为锁粒度,例如将订单创建、库存扣减、物流信息更新作为一个整体加锁。这样能确保数据一致性,但并发处理能力低,因为同一时间只有一个流程能执行。
- 细粒度:根据不同操作分拆锁,如订单创建、库存扣减、物流信息更新各加独立锁。这样可提高并发,因为不同操作可并行,但要注意操作顺序及锁之间的依赖关系,避免死锁。
- 按数据实体粒度:
- 粗粒度:以整个数据实体为锁粒度,如以订单表为锁对象,所有与订单相关操作都获取这把锁。这能保证订单数据一致性,但并发低。
- 细粒度:根据数据实体的属性或子集分拆锁,比如只对库存数量属性加锁用于库存扣减,对订单基本信息属性加锁用于订单创建。提高并发同时保证各部分数据一致性。
实现思路
- 基于业务操作粒度细粒度实现:
- 订单创建锁:在订单创建时,使用Redis的SETNX(SET if Not eXists)命令获取订单创建锁。例如:
SETNX order_create_lock {unique_value}
,unique_value
可以是UUID等唯一标识,释放锁时通过Lua脚本确保原子性删除。 - 库存扣减锁:库存扣减前,用同样SETNX获取库存扣减锁:
SETNX stock_deduction_lock {unique_value}
,操作完成后通过Lua脚本删除锁。 - 物流信息更新锁:物流信息更新前,获取物流信息更新锁:
SETNX logistics_update_lock {unique_value}
,操作完成后删除锁。 - 操作顺序与依赖:通过编排确保操作顺序,例如先获取订单创建锁,成功后再获取库存扣减锁,以此类推。同时设置合理的锁等待超时时间,防止死锁。
- 订单创建锁:在订单创建时,使用Redis的SETNX(SET if Not eXists)命令获取订单创建锁。例如:
- 基于数据实体粒度细粒度实现:
- 订单数据锁:对订单基本信息操作,获取订单基本信息锁:
SETNX order_base_info_lock {unique_value}
。 - 库存数据锁:对库存相关数据操作,获取库存数据锁:
SETNX stock_data_lock {unique_value}
。 - 物流数据锁:对物流相关数据操作,获取物流数据锁:
SETNX logistics_data_lock {unique_value}
。 - 数据一致性保证:在不同锁操作间,通过事务或补偿机制保证数据一致性。如库存扣减失败,回滚订单创建操作或进行补偿操作(如重新尝试扣减库存)。
- 订单数据锁:对订单基本信息操作,获取订单基本信息锁: