(热门面试题)Redis与数据库保证数据一致性(附带代码)

在无尽的八股文中突然醒悟,有感而发。redis作为日常开发的热门组件,不管在学习,还是在公司项目中都需要用到。接下来我们来聊一聊redis很热门的一个面试题:

面试官:用过redis吗?

我:用过。

面试官:那您能说说redis如何与数据库保证数据一致性?

我心想:啥玩意?我怎么不知道。

看完下面,你将不在迷茫。

那些杂七杂八的我这里不做阐述了,写了消耗眼球,解决不了什么屁事。

解决redis与数据库的读写一致性的解决办法:

  1. 先更新数据库再删除缓存(如果你只给面试官说这个,你是不会打动他的,最多知道你背了八股文)!

那如果你有代码相关的编写能够保证到你真正的解决过这个问题,他肯定眼前一亮。

/**
*查询接口
*/
@GetMapping("getData")
public R getData(Long id){
    //缓存有数据直接在缓存取数据
    if(redisUtil.exists(id.toString())){
        return redisUtil.get(id.toString());
    }
    //缓存没有数据进行数据库的查询与重新写入缓存的操作
    User user = userService.getById(id);
    redisUtil.set(id.toString(),user);
    return R.ok().data("user",user);
}
/**
*更新接口
*/
@PostMapping("updateData")
public R updateData(@RequestBody User user){
    //先更新数据库
    userService.updateById(user.getId());
    //删除缓存
    redisUtil.remove(user.getId().toString());
    return R.ok();
}

详细说一下代码的逻辑吧:

1、先更新数据库,在删除redis缓存。如果不删除缓存,下一次来读取的就是没有更新的数据。

2、读取数据时发现没有数据了,再重新查询数据库将更新好的数据放到redis中。

注意:

这样会存在一个高并发的问题

仍然两个请求,请求A更新数据库,请求B查询数据库。

(1) 缓存刚好失效;

(2) 请求B查询数据库,得到旧值;

(3) 请求A将新值写入数据库中;

(4) 请求A删除缓存;

(5) 请求B将查到的旧值写入缓存。

有问题肯定就有解决的办法了:

既然删第一次时候你进来插一脚,那我也可以等你走了继续再删一次(延时异步双删)。延时的这个时间得根据你开发的项目的实际情况来定。

代码也是在更新操作后稍微更改一下下就好。

/**
*查询接口
*/
@GetMapping("getData")
public R getData(Long id){
    //缓存有数据直接在缓存取数据
    if(redisUtil.exists(id.toString())){
        return redisUtil.get(id.toString());
    }
    //缓存没有数据进行数据库的查询与重新写入缓存的操作
    User user = userService.getById(id);
    redisUtil.set(id.toString(),user);
    return R.ok().data("user",user);
}
/**
*更新接口
*/
@PostMapping("updateData")
public R updateData(@RequestBody User user){
    //先更新数据库
    userService.updateById(user.getId());
    //删除缓存
    redisUtil.remove(user.getId().toString());
    //延时异步双删
    try {
        TimeUnit.SECONDS.sleep(secondsToSleep);
    } catch (InterruptedException ie) {
        Thread.currentThread().interrupt();
    }
    redisUtil.remove(user.getId().toString());
    return R.ok();
}

采用这个以后基本上能够解决redis与数据库的读写一致性了。你给面试官把这些说出来基本上面试稳了一半。希望能够帮助到和我一样在进步的小伙伴,觉得有帮助的扣扣大拇指哦。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值