mysql 验证出 bug 的经历

21 篇文章 0 订阅
  • 本人之前做了一个简单的会议预约系统
  • 逻辑非常的简单
  • 建立用户占用时间表 used_time
  • 和会议预约表 meeting_books
  • 规定会议时间以半小时为单位,最长不得超过两个小时
  • 用户每预定一个时间我就会向占用时间表里插入时间
  • 比如预定 08:00~09:00 我就会向占用时间表插入 08:0008:30
  • 08:0008:30 代表的是时间段的含义,是08:00~08:3008:30~09:00 的意思

预约创建的逻辑是
  1. 在占用时间表,验证请求时间是否被占用,没有则进行第2步,有则返回失败
  2. 创建预约,并将请求写入操作日志
  3. 向占用时间表插入数据

  • 假设用户选中 2018-08-30 08:00~09:00 的时间在一号会议室开会
  • 在创建订单的时候我会先从占用时间表 used_time 查找 一号会议室 2018-08-30 里有没有 08:0008:30
  • 如果有返回时间已被占用,创建失败
  • 没有就创建预约,并纪录日志
  • 然后再占用时间表里插入 一号会议室 2018-08-3008:0008:30 时间段
  • 最后返回 201 给前端

出现的问题
  • 但有一次出现了一个bug,一个用户再同一天同一个时间段创建了两个请求
  • 我当时很困惑,这个用户是怎么通过前端验证和后端验证的
  • 于是私聊她,她说是第一个请求时出现error 提示她失败
  • 于是她又重新立马创建了一个
  • 但是最后两个请求都成功了

伪代码逻辑
  • 这里为什么 createfindOrFail ,是因为 create 返回的是创建实例,而不是所有数据,我日志需要纪录所有数据
//创建数据
$meeting = meeting::create($data);

//查询数据
$meeting = meeting::findOrFail($meeting->id);

//纪录操作日志
Log::insert($meeting);
.......
//占用时间表插入
usedTime::insert($data);

问题出现的原因
  • 通过这番调查我大概明白了问题出现的原因
  • 线上数据库是读写分离的,主库写入,但更新数据后马上查询从库可能没来得及更新数据
  • 当网络不好时遇到从库更新不及时 findOrFail 就会报 404,导致后面所有操作都失效,自然验证也失效了
解决方法
  • 更新完后,查询指定使用主库
  • 更新后禁止查询,直接使用 create 返回的 model 实例,对于数据库中的有默认值的字段,手动加入到 model 实例中
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值