mysql 驗證出 bug 的經歷

  • 本人之前做了一個簡單的會議預約系統
  • 邏輯非常的簡單
  • 建立用戶佔用時間表 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 實例中
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章