प्रौद्योगिकी साझेदारी

कैश-वितरितं ताला-सिद्धान्तं मूलभूतं च उपयोगः

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

वितरित ताला सिद्धान्त एवं उपयोग

 

घूर्णन

  1. public Map<String, List<Catelog2Vo>> getCatalogJsonFromDBWithRedisLock() {
  2. Boolean b = redisTemplate.opsForValue().setIfAbsent(Lock, Lock, Duration.ofMinutes(1));
  3. if (!b) {
  4. int i = 10;
  5. while (i > 0) {
  6. Object result = redisTemplate.opsForValue().get(CATALOG_JSON);
  7. try {
  8. TimeUnit.MILLISECONDS.sleep(100);
  9. } catch (InterruptedException e) {
  10. throw new RuntimeException(e);
  11. }
  12. if (result != null) {
  13. System.out.println("命中缓存 db lock");
  14. return (Map<String, List<Catelog2Vo>>) result;
  15. }
  16. i--;
  17. }
  18. throw new RuntimeException("系统繁忙,请重新访问");
  19. }
  20. //1.查出所有1级分类
  21. List<CategoryEntity> selectList = baseMapper.selectList(null);
  22. /**
  23. * 将数据库的多次查询变成一次
  24. */
  25. System.out.println("查询了数据库");
  26. //2. 封装数据
  27. List<CategoryEntity> level1Category = selectList.stream().filter(s -> s.getParentCid().equals(0L)).collect(Collectors.toList());
  28. Map<String, List<Catelog2Vo>> map = level1Category.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {
  29. //1.每一个的一级分类,查到1级分类的所有二级分类
  30. List<CategoryEntity> categoryEntities = selectList.stream().filter(s -> s.getParentCid().equals(v.getCatId())).collect(Collectors.toList());
  31. List<Catelog2Vo> catelog2VoList = categoryEntities.stream().map(c -> {
  32. Catelog2Vo catelog2Vo = new Catelog2Vo();
  33. catelog2Vo.setId(c.getCatId().toString());
  34. catelog2Vo.setName(c.getName());
  35. catelog2Vo.setCatalog1Id(v.getCatId().toString());
  36. List<CategoryEntity> categoryEntities1 = selectList.stream().filter(s -> s.getParentCid().equals(c.getCatId())).collect(Collectors.toList());
  37. List<Catelog2Vo.Catelog3Vo> collect = categoryEntities1.stream().map(c3 -> {
  38. Catelog2Vo.Catelog3Vo catelog3Vo = new Catelog2Vo.Catelog3Vo();
  39. catelog3Vo.setId(c3.getCatId().toString());
  40. catelog3Vo.setName(c3.getName());
  41. catelog3Vo.setCatalog2Id(c.getCatId().toString());
  42. return catelog3Vo;
  43. }).collect(Collectors.toList());
  44. catelog2Vo.setCatalog3List(collect);
  45. return catelog2Vo;
  46. }).collect(Collectors.toList());
  47. return catelog2VoList;
  48. }));
  49. if (map == null) {
  50. /**
  51. * 解决缓存穿透
  52. */
  53. map = new HashMap<>();
  54. }
  55. redisTemplate.opsForValue().set(CATALOG_JSON, map, Duration.ofDays(1));
  56. redisTemplate.delete(Lock);
  57. return map;
  58. }

  1. public Map<String, List<Catelog2Vo>> getCatalogJsonFromDBWithRedisLock() {
  2. String uuid = UUID.randomUUID().toString();
  3. Boolean b = redisTemplate.opsForValue().setIfAbsent(Lock, uuid, Duration.ofMinutes(1));
  4. if (!b) {
  5. int i = 10;
  6. while (i > 0) {
  7. Object result = redisTemplate.opsForValue().get(CATALOG_JSON);
  8. try {
  9. TimeUnit.MILLISECONDS.sleep(100);
  10. } catch (InterruptedException e) {
  11. throw new RuntimeException(e);
  12. }
  13. if (result != null) {
  14. System.out.println("命中缓存 db lock");
  15. return (Map<String, List<Catelog2Vo>>) result;
  16. }
  17. i--;
  18. }
  19. throw new RuntimeException("系统繁忙,请重新访问");
  20. }
  21. //1.查出所有1级分类
  22. List<CategoryEntity> selectList = baseMapper.selectList(null);
  23. /**
  24. * 将数据库的多次查询变成一次
  25. */
  26. System.out.println("查询了数据库");
  27. //2. 封装数据
  28. List<CategoryEntity> level1Category = selectList.stream().filter(s -> s.getParentCid().equals(0L)).collect(Collectors.toList());
  29. Map<String, List<Catelog2Vo>> map = level1Category.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {
  30. //1.每一个的一级分类,查到1级分类的所有二级分类
  31. List<CategoryEntity> categoryEntities = selectList.stream().filter(s -> s.getParentCid().equals(v.getCatId())).collect(Collectors.toList());
  32. List<Catelog2Vo> catelog2VoList = categoryEntities.stream().map(c -> {
  33. Catelog2Vo catelog2Vo = new Catelog2Vo();
  34. catelog2Vo.setId(c.getCatId().toString());
  35. catelog2Vo.setName(c.getName());
  36. catelog2Vo.setCatalog1Id(v.getCatId().toString());
  37. List<CategoryEntity> categoryEntities1 = selectList.stream().filter(s -> s.getParentCid().equals(c.getCatId())).collect(Collectors.toList());
  38. List<Catelog2Vo.Catelog3Vo> collect = categoryEntities1.stream().map(c3 -> {
  39. Catelog2Vo.Catelog3Vo catelog3Vo = new Catelog2Vo.Catelog3Vo();
  40. catelog3Vo.setId(c3.getCatId().toString());
  41. catelog3Vo.setName(c3.getName());
  42. catelog3Vo.setCatalog2Id(c.getCatId().toString());
  43. return catelog3Vo;
  44. }).collect(Collectors.toList());
  45. catelog2Vo.setCatalog3List(collect);
  46. return catelog2Vo;
  47. }).collect(Collectors.toList());
  48. return catelog2VoList;
  49. }));
  50. if (map == null) {
  51. /**
  52. * 解决缓存穿透
  53. */
  54. map = new HashMap<>();
  55. }
  56. redisTemplate.opsForValue().set(CATALOG_JSON, map, Duration.ofDays(1));
  57. Object o = redisTemplate.opsForValue().get(Lock);
  58. if (o != null && o.equals(uuid)) {
  59. redisTemplate.delete(Lock);
  60. }
  61. return map;
  62. }

अद्यापि समस्या अस्ति

यतः संचरणप्रक्रियायां समयः भवति, यदि KEY इत्यस्य अवधिः अस्मिन् समये समाप्तः भवति तर्हि KEY इत्यस्य निर्माणार्थं अन्ये सूत्राणि आगच्छन्तु, ततः पूर्वसूत्रे दत्तांशः प्रत्यागच्छति यदि KEY इत्यस्य विलोपनं भवति तर्हि अन्यैः नवीनतया योजिताः कीलानि भविष्यन्ति लोपितः ।

मूल्यतुलना प्राप्नुवन्तु + सफलतापूर्वकं तुलनां कुर्वन्तु विलोपयन्तु = परमाणुसञ्चालनम्

redis+lua स्क्रिप्ट कार्यान्वयन

 public static final String Lock = "Lock";
  1. public Map<String, List<Catelog2Vo>> getCatalogJsonFromDBWithRedisLock() {
  2. String uuid = UUID.randomUUID().toString();
  3. Boolean b = redisTemplate.opsForValue().setIfAbsent(Lock, uuid, Duration.ofMinutes(5));
  4. if (!b) {
  5. System.out.println("获取分布式锁失败,等待重试");
  6. int i = 10;
  7. while (i > 0) {
  8. Object result = redisTemplate.opsForValue().get(CATALOG_JSON);
  9. try {
  10. TimeUnit.MILLISECONDS.sleep(100);
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. }
  14. if (result != null) {
  15. System.out.println("命中缓存 db lock");
  16. return (Map<String, List<Catelog2Vo>>) result;
  17. }
  18. i--;
  19. }
  20. throw new RuntimeException("系统繁忙,请重新访问");
  21. }
  22. //1.查出所有1级分类
  23. /**
  24. * 将数据库的多次查询变成一次
  25. */
  26. System.out.println("获取分布式锁成功");
  27. //2. 封装数据
  28. Map<String, List<Catelog2Vo>> map = null;
  29. try {
  30. System.out.println("查询了数据库");
  31. List<CategoryEntity> selectList = baseMapper.selectList(null);
  32. List<CategoryEntity> level1Category = selectList.stream().filter(s -> s.getParentCid().equals(0L)).collect(Collectors.toList());
  33. map = level1Category.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {
  34. //1.每一个的一级分类,查到1级分类的所有二级分类
  35. List<CategoryEntity> categoryEntities = selectList.stream().filter(s -> s.getParentCid().equals(v.getCatId())).collect(Collectors.toList());
  36. List<Catelog2Vo> catelog2VoList = categoryEntities.stream().map(c -> {
  37. Catelog2Vo catelog2Vo = new Catelog2Vo();
  38. catelog2Vo.setId(c.getCatId().toString());
  39. catelog2Vo.setName(c.getName());
  40. catelog2Vo.setCatalog1Id(v.getCatId().toString());
  41. List<CategoryEntity> categoryEntities1 = selectList.stream().filter(s -> s.getParentCid().equals(c.getCatId())).collect(Collectors.toList());
  42. List<Catelog2Vo.Catelog3Vo> collect = categoryEntities1.stream().map(c3 -> {
  43. Catelog2Vo.Catelog3Vo catelog3Vo = new Catelog2Vo.Catelog3Vo();
  44. catelog3Vo.setId(c3.getCatId().toString());
  45. catelog3Vo.setName(c3.getName());
  46. catelog3Vo.setCatalog2Id(c.getCatId().toString());
  47. return catelog3Vo;
  48. }).collect(Collectors.toList());
  49. catelog2Vo.setCatalog3List(collect);
  50. return catelog2Vo;
  51. }).collect(Collectors.toList());
  52. return catelog2VoList;
  53. }));
  54. if (map == null) {
  55. /**
  56. * 解决缓存穿透
  57. */
  58. map = new HashMap<>();
  59. }
  60. redisTemplate.opsForValue().set(CATALOG_JSON, map, Duration.ofDays(1));
  61. } catch (Exception e) {
  62. e.printStackTrace();
  63. } finally {
  64. //lua脚本解锁
  65. //如果获取key等于传过来的值,就执行删除操作,否则就不执行
  66. String script="if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
  67. Long execute = redisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class), Arrays.asList(Lock), uuid);
  68. if (execute==1){
  69. System.out.println("原子删锁成功");
  70. }else {
  71. System.out.println("原子删锁失败");
  72. }
  73. }
  74. return map;
  75. }

केवलं एकः एव दत्तांशकोशं पृष्टवान्