您的位置:首页 > 数据库 > Redis

yii2 redis队列,数据库表锁实现,点赞功能(10s内只可以点一次)

2017-09-26 18:09 459 查看
public function actionLike1(){
Yii::$app->response->format=Response::FORMAT_JSON;
if(Yii::$app->request->isGet){
return [
'msg'=>'Request Error!',
'state'=>(int)-1,
];
}
$data = @json_decode(file_get_contents("php://input","r"),true);
$topic_id=$data['topic_id'];
$bool=self::checkTopicId($topic_id);
if (!$bool){
return [
'msg'=>'话题不存在',
'state'=>'-1',
];
}
$redis = Yii::$app->redis;
$ip=Yii::$app->request->getUserIP();
//        $redis->del($topic_id.$ip);
//        $redis->del($topic_id.'likes');
//        $redis->del($topic_id.'log');
$bool=$redis->exists($topic_id.$ip);
/*队列最大长度*/
$max_leng=3;
/*点赞间隔*/
$time=1;
$data=json_encode(['ip'=>$ip,'topic_id'=>$topic_id,'created'=>time()],true);
if (!$bool){
//topic_id.ip 不存在,说明可以点赞,<10 加入队列
if ($leng=$redis->llen($topic_id.'log')<$max_leng){
$redis->lpush($topic_id.'log',$data);
//插入成功
if (!$redis->exists($topic_id.'likes')){
//执行sql查询content likes
$likes=self::redis_likes($topic_id);
//进行点赞了,likes+1
$redis->set($topic_id.'likes',$likes+1);
}else{
$redis->incr($topic_id.'likes');
}
$likes=$redis->get($topic_id.'likes');
//                var_dump('加入队列',$redis->lrange($topic_id.'log',0,-1));
}else{
//大于10
//事务,log content 入库
for ($i=0;$i<$max_leng;$i++){
$data=$redis->rpop($topic_id.'log');
$arr[]=json_decode($data,JSON_UNESCAPED_UNICODE);
}
//这一次的加入队列
$redis->lpush($topic_id.'log',$data);
//                var_dump('加入队列',$redis->lrange($topic_id.'log',0,-1));

//content likes +10;
$transaction=Yii::$app->db->beginTransaction(\yii\db\Transaction::SERIALIZABLE);
try{
$sql="select likes from {{%mediacloud_content}} where topic_id=:topic_id for update";
$info=Yii::$app->db->createCommand($sql)->bindValue(':topic_id',$topic_id)->queryOne();
//现在点赞的人数 +1 因 进行一次请求
$likes=$info['likes']+$max_leng+1;
/*点赞量入库*/
$sql="update {{%mediacloud_content}} set likes=likes+$max_leng WHERE topic_id=:topic_id";
Yii::$app->db->createCommand($sql)->bindValue(':topic_id',$topic_id)->execute();
//此时数据库 与缓存是一致的
$redis->set($topic_id.'likes',$likes);

/*log入库*/
$bool=Yii::$app->db->createCommand()->batchInsert(LikeLog::tableName(),['ip','topic_id','created'],$arr)->execute();
if ($bool==0){
throw new Exception('点赞日志入库失败');
}
$transaction->commit();
}catch (Exception $e){
//                    var_dump($e->getMessage());
$transaction->rollBack();
return '点赞失败'.$e->getMessage();
}
}
/*10s内存在说明,不能点赞*/
$redis->set($topic_id.$ip,'','ex',$time);
return [
'msg'=>'ok',
'state'=>(int)0,
'likes'=>(int)$likes,
];
}else{
$likes=$redis->get($topic_id.'likes');
if (empty($likes)){
$likes=self::redis_likes($topic_id);
}
return [
'msg'=>'请勿重复点赞',
'state'=>(int)0,
'likes'=>(int)$likes,
];
}

}

public function actionGetlikes1(){
Yii::$app->response->format=Response::FORMAT_JSON;
if (Yii::$app->request->isPost){
return [
'msg'=>'Request Error!',
'state'=>(int)-1,
];
}
$topic_id=Yii::$app->request->get('topic_id');
$bool=self::checkTopicId($topic_id);
if (!$bool){
return [
'msg'=>'话题不存在',
'state'=>'-1',
];
}
$redis=Yii::$app->redis;
$likes=$redis->get($topic_id.'likes');
if (empty($likes)){
$likes=self::redis_likes($topic_id);
$redis->set($topic_id.'likes',$likes);
}
return [
'msg'=>'ok',
'state'=>(int)0,
'likes'=>(int)$likes,
];
}

public function redis_likes($topic_id){
//执行sql查询content likes
$likes=MediaCloudContent::find()->where(['topic_id'=>$topic_id])->select('likes')->asArray()->one()['likes'];
//进行点赞了,likes+1
return $likes;
}
public function checkTopicId($topic_id){
$content=MediaCloudContent::find()->where(['topic_id'=>$topic_id])->select(['topic_id'])->asArray()->one();
if (!$content){
return false;
}else{
return true;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐