业务类中处理点赞、收藏和浏览量

描述

点赞、收藏、浏览量等信息的存储位置取决于具体的业务需求和系统架构,但通常会结合数据库和缓存来进行设计。

常见的做法是:

初始时,将点赞、收藏、浏览量等信息存储在数据库中。

然后,将这些数据同步到缓存中,并在用户进行相关操作(如点赞、收藏)时,同时更新数据库和缓存。

这样可以在保证数据准确性的同时,提高系统的性能和响应速度。

改进

以下是一种可能更优的方案,考虑了数据一致性、并发处理和性能优化:

引入分布式锁:

在对点赞、收藏和浏览量进行操作时,获取分布式锁,以确保并发情况下数据的准确性。

异步更新数据库:

先更新缓存,然后将更新数据库的操作放入消息队列中异步处理,以提高响应速度。

缓存预热:

在系统启动或定期将热门文章的相关数据加载到缓存中,减少首次访问时的数据库查询。

点击查看代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class ArticleService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private ArticleRepository articleRepository;

    @Autowired
    private DistributedLockManager lockManager;  // 假设使用分布式锁管理组件

    @Autowired
    private MessageQueueProducer messageQueueProducer;  // 消息队列生产者

    // 增加点赞数
    @Transactional
    public void incrementLikes(Long articleId) {
        String lockKey = "article_likes_lock:" + articleId;
        try {
            // 获取分布式锁
            if (lockManager.acquireLock(lockKey)) {
                String likesKey = "article_likes:" + articleId;
                Long likesInCache = redisTemplate.opsForValue().increment(likesKey, 1);

                // 将更新数据库的操作放入消息队列异步处理
                messageQueueProducer.sendUpdateLikesMessage(articleId, likesInCache);
            }
        } finally {
            // 释放锁
            lockManager.releaseLock(lockKey);
        }
    }

    // 增加收藏数和浏览量的方法类似

    // 获取点赞数
    public Long getLikes(Long articleId) {
        String likesKey = "article_likes:" + articleId;
        Long likesInCache = redisTemplate.opsForValue().get(likesKey);

        if (likesInCache == null) {
            // 如果 Redis 中没有,从数据库中获取并设置到 Redis 中
            Long likesInDB = articleRepository.getLikes(articleId);
            if (likesInDB!= null) {
                redisTemplate.opsForValue().set(likesKey, likesInDB.toString());
                return likesInDB;
            }
            return 0L;
        } else {
            return Long.parseLong(likesInCache);
        }
    }

    // 类似地实现获取收藏数和浏览量的方法
}

核心部分:

posted @ 2024-09-04 20:49  锅巴编程  阅读(34)  评论(0编辑  收藏  举报