- 本人之前做了一個簡單的會議預約系統
- 邏輯非常的簡單
- 建立用戶佔用時間表
used_time
- 和會議預約表
meeting_books
- 規定會議時間以半小時爲單位,最長不得超過兩個小時
- 用戶每預定一個時間我就會向佔用時間表裏插入時間
- 比如預定
08:00~09:00
我就會向佔用時間表插入 08:00
和08:30
08:00
和08:30
代表的是時間段的含義,是08:00~08:30
和 08:30~09:00
的意思
預約創建的邏輯是
- 在佔用時間表,驗證請求時間是否被佔用,沒有則進行第2步,有則返回失敗
- 創建預約,並將請求寫入操作日誌
- 向佔用時間表插入數據
- 假設用戶選中
2018-08-30 08:00~09:00
的時間在一號會議室開會
- 在創建訂單的時候我會先從佔用時間表
used_time
查找 一號會議室 2018-08-30
裏有沒有 08:00
和08:30
- 如果有返回時間已被佔用,創建失敗
- 沒有就創建預約,並紀錄日誌
- 然後再佔用時間表裏插入
一號會議室 2018-08-30
的 08:00
和08:30
時間段
- 最後返回
201
給前端
出現的問題
- 但有一次出現了一個bug,一個用戶再同一天同一個時間段創建了兩個請求
- 我當時很困惑,這個用戶是怎麼通過前端驗證和後端驗證的
- 於是私聊她,她說是第一個請求時出現
error
提示她失敗
- 於是她又重新立馬創建了一個
- 但是最後兩個請求都成功了
僞代碼邏輯
- 這裏爲什麼
create
後 findOrFail
,是因爲 create
返回的是創建實例,而不是所有數據,我日誌需要紀錄所有數據
//創建數據
$meeting = meeting::create($data);
//查詢數據
$meeting = meeting::findOrFail($meeting->id);
//紀錄操作日誌
Log::insert($meeting);
.......
//佔用時間表插入
usedTime::insert($data);
問題出現的原因
- 通過這番調查我大概明白了問題出現的原因
- 線上數據庫是讀寫分離的,主庫寫入,但更新數據後馬上查詢,從庫可能沒來得及更新數據
- 當網絡不好時遇到從庫更新不及時
findOrFail
就會報 404
,導致後面所有操作都失效,自然驗證也失效了
解決方法
- 更新完後,查詢指定使用主庫
- 更新後
禁止查詢
,直接使用 create
返回的 model
實例,對於數據庫中的有默認值的字段,手動加入到 model
實例中