Springboot缓存+定时提交优化频繁数据库表修改

缘起

最近在弄一个答题小程序,当用户选择的时候需要把用户选择的选项提交到服务器上,然后整个字段是个json格式的,更新的方法也就是解析json后添加选项进入json中。
于是其中就涉及到频繁的数据库修改,因为用户答题速度根据题目不同嘛,所以我就寻思这样频繁的修改,数据量上来速度就会受到较大的影响。
于是我打算在服务端做一个缓存机制,保存从数据库中读取到的记录用户选项的字段,这样修改就会快一些,然后利用spring的@Scheduled进行定时提交到数据库

springboot后端写法

缓存机制

利用一个ConcurrentHashMap,记录userId和对象,当获取这个字段时,判断是否存在有效的对象,如果存在,直接从map中返回,并且更新缓存的过期时间


public Map<String, UserGroupProgress> getUserGroupProgress(Integer userId) {
        if ( !userGroupProgressMap.containsKey(userId) ){
            log.info("get userProgress from database");
            // 对象不存在,从数据库中读取
            User user = userService.lambdaQuery().select(User::getGroupProgress).eq(User::getId, userId).one();
            if ( user == null ){
                return null;
            }
            UserGroupProgressCache cache = new UserGroupProgressCache();

            cache.setMap(user.getGroupProgress());
            cache.setCacheTime(System.currentTimeMillis());


            userGroupProgressMap.put(userId, cache);
            return cache.getMap();
        }
        log.info("get userProgress from map");
        UserGroupProgressCache cache = userGroupProgressMap.get(userId);
        // 更新缓存时间
        cache.setCacheTime(System.currentTimeMillis());

        return cache.getMap();
    }

然后再application启动类中加上 @EnableScheduling 注解

@EnableScheduling
@SpringBootApplication
public class CloudQuestionApplication {

    public static void main(String[] args) {
        SpringApplication.run(CloudQuestionApplication.class, args);
    }

}

定时提交

使用 @Scheduled 注解进行定时提交,并且检查缓存是否过期


    // 这里是测试,所以才定的30s
    @Scheduled(fixedDelay = 30000)
    public void executeProgressSubmit() {
        // 遍历整个map,提交一轮,如果过期,直接抛弃,缓存20分钟

      // 这里主要用于测试,没啥实际作用
        int commitCount = 0, removeCount = 0;

        Long time = System.currentTimeMillis();
        for (Map.Entry<Integer, UserGroupProgressCache> entry : userGroupProgressMap.entrySet()) {
            commitCount ++;
            if ( entry.getValue() == null ){
                continue;
            }

            userService.lambdaUpdate()
                    .set(User::getGroupProgress, JSON.toJSONString(entry.getValue().getMap()))
                    .eq(User::getId, entry.getKey())
                    .update();

            if ( time - entry.getValue().getCacheTime() > 1000 * 60 * 20 ){
                // 抛弃对象
                removeCount ++;
                userGroupProgressMap.remove(entry.getKey());
            }

        }

    }

前端写法


前端还考虑集贸,直接提交即可

posted @ 2024-10-17 12:31  陌路只爱睡大觉  阅读(9)  评论(0编辑  收藏  举报