我有一张桌子,Foo。我在某些事件上向此表添加行。目前的整体设计使得无法避免重复的消息。这导致向表中添加重复的行。
我不能在表上放置唯一约束,因为在此表中有不同类型的消息成为行。我想避免仅针对特定类型的消息重复。
由于重复消息通常同时发生,并且该应用程序在多个节点上运行,因此我决定使用radisson来进行分布式锁定。但它似乎没有起作用。我仍然在表中获得重复的行。
根据userId,日期和类型检测重复邮件。下面是简约的演示代码。我试图在写入之前进行读取,并且此读取发生在跨应用程序节点的同步块中。
感谢对此的任何意见。
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();
}
答案 0 :(得分:0)
我发现了这个问题。上面的代码块在@Transactional中。使用spring默认隔离级别,它在mysql上是REPEATABLE_READ。取决于交易之外的锁定问题。
答案 1 :(得分:0)
MyEntity myEntity = myEntityRepository.findByUserIdAndDateAndActivityType(userId,date,Type.XYZ);
if(null == myEntity) {
myEntity = new MyEntity();
// myEntity setters
myEntity = myEntityRepository.saveAndFlush(myEntity);
}
根据此部分代码,您将userId,date和type视为唯一条件,以决定是否可以插入此记录。所以你能解释一下为什么你不能将它们组合在一起作为一个独特的组合约束。