我们使用 springboot 3.2.5 和 spring data jpa 将数据插入 RDBMS。 现在需要确保重复数据不会插入到 RDBMS 中。
所以我们首先要根据key检查数据记录是否已经插入,然后检查Redis是否包含该key,如果包含该key,则返回保存的实体的标识符。
如果 Redis 中不存在该键 - 第一次请求时,创建一个新的 Redis 键,然后将该键保存在 Redis 中,然后将数据插入 RDBMS,一旦插入成功,将标识符更新为该键对应的 Redis 值.
我们正在使用 Redis,需要确保在原子操作中检查密钥是否存在并创建新密钥(如果不存在)——意味着这需要在单个事务中进行。我们使用的是 spring data redis 3.2.X JSON,其中包含 Lettuce。请帮忙。
我们目前使用简单的 Redis 命令,例如 set 和 get,使用 lettuce ProtocolKeyword 来执行命令。 Redis 文档建议使用 MULTI 和 EXEC,但不确定 Lettuce 是否可以使用这些(Lettuce 文档无法访问)
有一些使用管道和事务的方法,我们倾向于事务的原子性。不过,我还没有找到可行的方法来在代码中做到这一点。
您面临的最大挑战是您想要原子地
现在,您正在两个不同的未链接的数据源之间进行操作,因此纯粹的原子机制根本不可能,MULTI/EXEC 将无济于事,因为您正在这些数据源之间进行操作。但是,您可以使用分布式锁确保一次只有一名写入者。
假设您坚持使用简单的字符串键,让我们调用您要使用的数据键
key:1
将
SET
与 NX
命令和 EX
选项一起使用,可以在某些锁定键上发布超时,例如key:1:lock
- 例如
SET key:1:lock 1 NX EX 10
这会将值 1 写入该键 仅如果 Redis 中尚不存在该键,并且它将在 10 秒后自动使该键过期(以防您的线程因某种原因终止)
如果你收到
OK
结果,这意味着你已经获得了锁,如果你得到 null
那么你知道另一个线程已经获得了锁,你可以在这里终止或退出并稍后重试
您现在可以编写数据库 - 这应该是非常不言自明的
现在您将把实际数据写入Redis,并且您将删除锁定键,允许其他线程更新数据,您可以使用SET和UNLINK来完成此操作
SET key:1 your_data
UNLINK key:1:lock