面试题答案
一键面试数据结构选择
- 使用Redis的
SET
数据结构:用于存储当前正在处理订单的标识,以防止重复创建订单。例如,以订单号作为SET
的成员。 - 使用Redis的
HASH
数据结构:记录商品库存等关键业务数据。以商品ID作为HASH
的键,库存数量作为字段值。这样可以方便地进行原子性的库存增减操作。
操作流程
- 订单创建前:
- 首先,尝试将订单号添加到
SET
中,使用SADD
命令。例如,SADD order_set {order_number}
。如果返回值为1,表示添加成功,说明该订单尚未处理,可以继续后续操作;如果返回值为0,说明订单已在处理中,拒绝本次订单创建请求。 - 从
HASH
中获取商品库存信息,使用HGET
命令。例如,HGET product_stock {product_id}
,获取商品当前库存数量。
- 首先,尝试将订单号添加到
- 订单创建过程中:
- 使用
HINCRBY
命令原子性地减少商品库存。例如,HINCRBY product_stock {product_id} -1
,减少一件商品库存。 - 进行MySQL中涉及的多表关联操作,如插入订单数据到订单表,更新用户表相关信息(如积分等),同时要确保这些数据库操作在一个事务中。
- 使用
- 订单创建成功后:
- 从
SET
中移除订单号,使用SREM
命令。例如,SREM order_set {order_number}
,表示该订单已处理完成。
- 从
异常情况处理
- Redis操作异常:
- 如果
SADD
操作失败,可能是Redis服务暂时不可用,此时应记录错误日志,并进行重试。可以设置重试次数,如重试3次,如果仍然失败,返回给用户错误信息,告知系统繁忙,请稍后重试。 - 如果
HGET
、HINCRBY
等操作失败,同样记录错误日志并进行重试。若重试失败,回滚MySQL中的事务操作,确保数据一致性。
- 如果
- MySQL事务异常:
- 如果MySQL事务提交失败,回滚事务,并在Redis中恢复库存。例如,使用
HINCRBY
命令将之前减少的库存加回来,HINCRBY product_stock {product_id} 1
。同时,从SET
中移除订单号(如果已添加),以允许后续重试订单创建。
- 如果MySQL事务提交失败,回滚事务,并在Redis中恢复库存。例如,使用
- 网络异常:
- 在操作过程中如果出现网络异常,无论是Redis还是MySQL操作,都应记录当前操作进度。例如,记录已经完成的Redis操作和MySQL事务执行到哪一步。当网络恢复后,根据记录的进度进行相应的补偿操作,要么重试未完成的操作,要么回滚已部分完成的操作,保证数据的一致性。