From 445048590141109f87e97a58833ccdbc2498e48a Mon Sep 17 00:00:00 2001 From: Kirk Lin Date: Wed, 23 Jun 2021 17:59:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=89=E7=BA=A7=E8=8F=9C=E5=8D=95=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E7=9A=84Redis=E5=88=86=E5=B8=83=E5=BC=8F=E9=94=81?= =?UTF-8?q?=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/CategoryServiceImpl.java | 51 +++++++++++++++++-- .../src/main/resources/application.yml | 2 +- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/kkmall-product/src/main/java/name/lkk/kkmall/product/service/impl/CategoryServiceImpl.java b/kkmall-product/src/main/java/name/lkk/kkmall/product/service/impl/CategoryServiceImpl.java index 945dca8..e6a8a18 100644 --- a/kkmall-product/src/main/java/name/lkk/kkmall/product/service/impl/CategoryServiceImpl.java +++ b/kkmall-product/src/main/java/name/lkk/kkmall/product/service/impl/CategoryServiceImpl.java @@ -5,6 +5,7 @@ import com.alibaba.fastjson.TypeReference; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; import name.lkk.common.utils.PageUtils; import name.lkk.common.utils.Query; import name.lkk.kkmall.product.dao.CategoryDao; @@ -16,16 +17,16 @@ import name.lkk.kkmall.product.vo.Catelog2Vo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ValueOperations; +import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; - +@Slf4j @Service("categoryService") public class CategoryServiceImpl extends ServiceImpl implements CategoryService { @@ -130,17 +131,56 @@ public class CategoryServiceImpl extends ServiceImpl>>() { }); } return catelogJson; } + /** + * 分布式锁 + * + * @return + */ + public Map> getCatelogJsonFromDBWithRedisLock() { + String uuid = UUID.randomUUID().toString(); + // 1.占分布式锁 设置这个锁30秒自动删除 [原子操作] + Boolean lock = stringRedisTemplate.opsForValue().setIfAbsent("lock", uuid, 30, TimeUnit.SECONDS); + + if (lock) { + // 2.设置过期时间加锁成功 获取数据释放锁 [分布式下必须是Lua脚本删锁,不然会因为业务处理时间、网络延迟等等引起数据还没返回锁过期或者返回的过程中过期 然后把别人的锁删了] + Map> data; + try { + data = getCatelogJsonFormDB(); + } finally { +// stringRedisTemplate.delete("lock"); + // String lockValue = stringRedisTemplate.opsForValue().get("lock"); + + // 删除也必须是原子操作 Lua脚本操作 删除成功返回1 否则返回0 + String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end"; + // 原子删锁 + stringRedisTemplate.execute(new DefaultRedisScript(script, Long.class), Collections.singletonList("lock"), uuid); + } + return data; + } else { + // 重试加锁 + //暂停200毫秒线程 + try { + log.debug("Redis已加锁,等待重试"); + TimeUnit.MILLISECONDS.sleep(200); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return getCatelogJsonFromDBWithRedisLock(); + } + } + /** * 从数据库中查询CatelogJson + * * @return */ public Map> getCatelogJsonFormDB() { @@ -150,6 +190,7 @@ public class CategoryServiceImpl extends ServiceImpl>>() { }); } + log.debug("getCatelogJsonFormDB() ==> REDIS中无数据,正在查询数据"); // 优化:将查询变为一次 List entityList = baseMapper.selectList(null); @@ -189,7 +230,7 @@ public class CategoryServiceImpl extends ServiceImpl entityList = baseMapper.selectList(null); diff --git a/kkmall-product/src/main/resources/application.yml b/kkmall-product/src/main/resources/application.yml index bb4d0f3..7ada551 100644 --- a/kkmall-product/src/main/resources/application.yml +++ b/kkmall-product/src/main/resources/application.yml @@ -38,4 +38,4 @@ server: logging: level: - name.lkk.kkmall: error \ No newline at end of file + name.lkk.kkmall: debug \ No newline at end of file