1. 通过数据状态(未处理、处理中、处理完成)
2. 分页 分层
3. 通过数据锁定 select for update (多线程安全)
4. 事务
实例:
用户表、兑换资格表、兑换资格统计表
1. 千万用户
2. 用户通过签到获取若干兑换资格
3. 定时任务在固定时间统计每个用户去年未兑换的资格总数
4. 用户可手动兑换,此时 未兑换->兑换中 ,也需要更新统计表
具体实现:
通过select 非处理中用户并加锁,然后更新处理状态为(处理中)
循环处理这N条数据。
for{
锁定统计表
更新统计信息
更新用户表为处理完成(这三步在同一个事务里)
}
问题1:定时任务多线程处理每个用户如何不重复
通过select 锁定 N 条用户,然后把这些用户更新为资格统计中。(这两步在同一个事务里)
然后处理这N个用户(在另外的事务里)
问题2:如果处理结束出现异常,用户表状态依旧是处理中 怎么办?如何区分是正在处理还是处理异常?
手动更新某个时间点之前的所有处理中为未处理,比如10天前。此时即便两个线程同时处理,由于统计表被锁,也会先后处理,不存在数据安全问题。