讨论数量:
你这不是个典型的出列入列嘛!
首先表中有100条数据 user_id=0
对吧? 采用抢占式分配数据,如果你用表锁的话,高并发的话失败成功率太高了。
不如直接把这 user_id=0
的 100条 id
放入 redis list
,通过 push
pop
的方式来分配数据,这样数据库既没有压力,速度也快很多。只不过需要写一个脚本把这100条 user_id=0
的先入列到 redis
。
// Redis push
$rows = Code::where('user_id', 0)->get();
$redis = new Redis();
foreach($rows as $row) {
$redis->rpush('user_id_0_queue', $row->id);
}
// Redis pop
if($id = $redis->lpop('user_id_0_queue')) {
Code::where('id', $id)->update(['user_id' => Auth::id()]);
} else {
return '号都发完啦!';
}
在 MySQL 中实现同时将 100 条数据分给 100 个不同的人,需要解决并发问题,防止两个或多个用户同时修改同一条数据,导致数据不一致。下面是一种可能的解决方案:
查询出 user_id=0 的前 100 条数据,使用 SELECT FOR UPDATE 查询锁定这些数据,锁定这些数据可以避免其他人同时修改同一条数据。
将这些数据分成 100 组,每组有一条数据,分给不同的人处理,通过使用 MySQL 事务,确保这些修改操作是原子性的,要么全部成功要么全部失败,避免数据不一致。
下面是示例代码:
BEGIN;
SELECT id FROM code WHERE user_id=0 LIMIT 100 FOR UPDATE;
UPDATE code SET user_id=1 WHERE id IN (1, 2, 3, ..., 100);
COMMIT;
其中 SELECT ... FOR UPDATE 语句会锁定查询结果,防止其他人同时修改数据。UPDATE 语句会将这些数据的 user_id 修改为 1,表示这些数据已经被处理。如果在修改数据时发生了错误,事务会回滚,恢复数据到修改之前的状态
你这不是个典型的出列入列嘛!
首先表中有100条数据
user_id=0
对吧? 采用抢占式分配数据,如果你用表锁的话,高并发的话失败成功率太高了。不如直接把这
user_id=0
的 100条id
放入redis list
,通过push
pop
的方式来分配数据,这样数据库既没有压力,速度也快很多。只不过需要写一个脚本把这100条user_id=0
的先入列到redis
。