net core 使用redis 分布式锁

在电商项目中,必定会与订单打交道。订单中必定会涉及到扣库存,但是在高并发项目中,库存余量不能及时刷新,导致库存扣除得不正确,1000个并发请求下来,扣除的库存只有几十个。如何解决此问题,那就得加锁了。还有其他解决办法也能处理此问题,本文只分享一下redis 分布式锁解决此问题。

第一步添加一个redis的获取锁,与释放锁的方法。在获取锁时,如果未获取到锁,那么就会尝试重复获取,直到获取倒锁后,才返回。当然在这步你可以加一个超时时间,例如最多尝试获取30秒,避免释放锁异常在此一直死循环。释放锁时只有锁的拥有者才能释放锁,避免锁被其他线程释放了,这个分布式锁就没有意义了。

 public class RedisDistributedLock
 {
     private readonly ConnectionMultiplexer _redis;
     private readonly IDatabase _database;

     public RedisDistributedLock(ConnectionMultiplexer redis)
     {
         _redis = redis;
         _database = redis.GetDatabase();
     }

     public async Task<bool> AcquireLockAsync(string lockKey, string value, TimeSpan lockTimeout)
     {
         var acquired = await _database.StringSetAsync(lockKey, value, lockTimeout, When.NotExists);
         if (!acquired)
         {
### Spring Boot 实现 Redis 分布式锁分布式环境中,为了防止多个实例同时处理相同的数据而导致数据不一致的情况发生,在 Spring Boot 应用程序中可以利用 Redis 来创建分布式锁。下面介绍一种基于 Redis 的简单而有效的分布式锁实现方式。 #### 使用 Lettuce 客户端操作 Redis 锁 Lettuce 是一个线程安全的客户端库,支持异步执行命令以及自动重连机制等功能特性,非常适合用来构建高可用的应用场景下的分布式锁服务[^1]。 ```java import io.lettuce.core.RedisClient; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; public class DistributedLock { private final String lockKey; // 锁键名 private final long expireTimeMs; // 过期时间毫秒数 public DistributedLock(String key, int timeoutSecs){ this.lockKey = "lock:" + key; this.expireTimeMs = (long)(timeoutSecs * 1000); } /** * 尝试获取锁 */ public boolean tryAcquire(){ StatefulRedisConnection<String, String> connection = null; try{ RedisClient client = RedisClient.create("redis://localhost"); connection = client.connect(); RedisCommands<String, String> syncCmds = connection.sync(); Long result = syncCmds.set(lockKey,"locked", SetArgs.Builder.nx().px(expireTimeMs)); return Objects.nonNull(result) && Boolean.TRUE.equals(result==1); } finally { if(connection != null){ connection.close(); } } } /** * 释放锁 */ public void release() throws Exception{ StatefulRedisConnection<String, String> connection = null; try{ RedisClient client = RedisClient.create("redis://localhost"); connection = client.connect(); RedisCommands<String, String> syncCmds = connection.sync(); // 只有当 value 值相等时才删除该 key-value 对应关系 syncCmds.eval( "if redis.call('get', KEYS[1]) == ARGV[1]" + "then return redis.call('del', KEYS[1])" + "else return 0 end", Arrays.asList(lockKey), Collections.singletonList("locked")); }finally{ if(connection!=null){ connection.close(); } } } } ``` 此代码片段展示了如何通过 `SET` 命令设置带有过期时间和条件(仅当不存在指定key时才会成功)参数来尝试获得锁;并通过 Lua 脚本原子化地检查并移除已存在的锁记录以确保安全性[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值