1

我确实有一张桌子,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();
     }
4

2 回答 2

0

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

于 2017-05-16T15:14:43.030 回答
0
MyEntity myEntity = myEntityRepository.findByUserIdAndDateAndActivityType(userId,date,Type.XYZ);
if(null == myEntity) {
   myEntity = new MyEntity();
   // myEntity setters
   myEntity = myEntityRepository.saveAndFlush(myEntity);
}

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

于 2017-06-21T18:58:44.457 回答