文章目录
场景
- 先查询,不存在则插入,存在则更新
- 更新需依赖于之前的记录并做复杂的计算,无法使用 “INSERT … ON DUPLICATE KEY UPDATE” 解决
问题
两个请求 A 和 B 如果同时到来,那么可能出现以下序列:
- A select 记录不存在
- B select 记录不存在
- A 插入
- B 插入
从而出现重复插入的情况。
解决方案
LOCK TABLE
这种方式会锁全表,导致并发性能下降,此外,如果在 LOCK TABLE
和 UNLOCK TABLE
之间有异常,会导致锁无法释放,因此,暂时不考虑这种方案。
INSERT IGNORE
设置查询字段为 UNIQUE KEY, INSERT 时增加 IGNORE
, 当重复插入时,不返回错误,但 affected_rows 为 0.
具体实现为:
local ok, task = CheckTask(params)
if not ok then
ngx.log(ngx.ERR, task)
utils.response(-1, task)
end
local task_id, err = CreateOrUpdateTask(params, task)
if not task_i