30、redis事务
1、redis悲观锁
悲观锁 顾名思义很悲观,认为每次都会失败,每次操作都会加上锁,只有等到锁释放之后才能操作、这种效率不高
2、redis乐观锁
乐观锁顾名思义很乐观,认为每次操作都不会失败,操作时通过数据版本号来决定是否成功,在操作的时首先获取版本号判断是否一致,如果一致那么成功并把版本号加一,如果不一致就操作失败
3、redis事务的特征
1、单独的隔离性
2、没有隔离级别的概念
3、不保证原子性:在事务中如果某一个操作失败,不会影响其他命令
4、redis 缓存穿透
是指缓存中没有数据,数据库中也没有数据,导致大量的请求去访问数据库,从而导致服务器崩掉
解决方案:1、在接口层加校验参数,2、缓存中没有的数据库中也没有的数据,用key-null存储到缓存中
5、redis缓存击穿
是指缓存中没有的数据,但是数据库中存在,那么导致大量的这个key请求到数据到数据库中,导致数据库的压力瞬间变大数据库崩溃
解决方案:可以对热点数据不加过期时间,2、使用自旋锁
6、redis缓存雪崩:
在同一时间内缓存大面积失效,导致同一时间去访问数据库,数据库压力巨大导致崩溃
解决方案:缓存预热、互斥锁
7、redis 分布式锁
什么时分布式锁:在集群环境中操作一个共享数据,因为多个服务器中不认识这个锁,单机是可以实现的。
1、手动加锁:setnx key,手动释放锁: del key
2、锁一直没有被释放,设置key的过期时间,自动释放这个锁
3、上锁之后突然发生异常,无法设置过期时间, 在上锁的时候并且把过期时间一并设置 命令:set users 10 nx ex 20
8、redisTemplate实现分布式锁,并且防止锁被误删
@RestController public class TestRedisController { @Autowired private RedisTemplate redisTemplate; @GetMapping(value = "/testLock") public void testLock() { String uuid = UUID.randomUUID().toString(); //加上锁 Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 10, TimeUnit.SECONDS); if(lock) { Object value = redisTemplate.opsForValue().get("num"); if (StringUtils.isEmpty(value)){ redisTemplate.opsForValue().set("num",1); return; } int num = Integer.parseInt(value + ""); redisTemplate.opsForValue().set("num",num++); String redisUuid = (String) redisTemplate.opsForValue().get("lock"); if(uuid.equals(redisUuid)) { //释放锁 Boolean lock1 = redisTemplate.delete("lock"); } }else { try { Thread.sleep(3000); }catch (Exception e) { e.printStackTrace(); } } } }
9、redis五大数据类型的使用场景
striing 类型:一般用来分布式锁、某种商品的点赞数量
list 类型:我收藏的文章订阅号
hash 类型:java Map<String,Map<Object,Object>>
set 类型 :数据计算。共同的好像
zset 类型:商品购买数量排序

浙公网安备 33010602011771号