【问题标题】:Avoiding duplicate rows via redisson通过 redisson 避免重复行
【发布时间】:2017-05-15 14:58:58
【问题描述】:

我确实有一张桌子,Foo。我在某些事件上向此表添加行。当前的总体设计使得无法避免重复消息。这会导致向表中添加重复行。

我不能对表设置唯一约束,因为有不同类型的消息会成为该表中的行。我想避免仅针对特定类型的消息重复。

由于重复消息经常同时出现,并且该应用程序在多个节点上运行,我决定使用 radisson 来获取分布式锁。但是,它似乎不起作用。我仍然在表中得到重复的行。

根据用户 ID、日期和类型检测重复消息。下面是简约的演示代码。我正在尝试在写入之前进行读取,并且此读取发生在跨应用程序节点的同步块中。

感谢您对此的任何意见。

     if(updateEntry.getType().equals(Type.XYZ) {
       java.sql.Date date = updateEntry.getDate();
       String redisLockKey = "MyAPP" + "-" + userId+"-"+date.toString()+ "-" + "type-XYZ";
       RLock rLock =    redissonClient.getLock(redisLockKey);
       rLock.lock(5, TimeUnit.SECONDS);
       MyEntity myEntity = myEntityRepository.findByUserIdAndDateAndActivityType(userId,date,Type.XYZ);
       if(null == myEntity) {
           myEntity = new MyEntity();
           // myEntity setters
        myEntity = myEntityRepository.saveAndFlush(myEntity);
       }
       rLock.unlock();
     }

【问题讨论】:

    标签: mysql redis duplicates redisson distributed-lock


    【解决方案1】:

    我发现了问题。上面的代码块在@Transactional 中。使用 spring 默认隔离级别,它是 mysql 的 REPEATABLE_READ。在事务之外使用锁解决了这个问题。

    【讨论】:

      【解决方案2】:
      MyEntity myEntity = myEntityRepository.findByUserIdAndDateAndActivityType(userId,date,Type.XYZ);
      if(null == myEntity) {
         myEntity = new MyEntity();
         // myEntity setters
         myEntity = myEntityRepository.saveAndFlush(myEntity);
      }
      

      根据这部分代码,您将 userId、date 和 type 作为唯一标准来决定是否可以插入此记录。所以你能解释为什么你不能把它们三个一起作为一个组合的唯一约束。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-03-17
        • 2013-09-04
        • 2017-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-21
        相关资源
        最近更新 更多