做项目时遇到一个功能,需要3步,1)通过solr取一个已审核数,然后和可通过数进行比较 2)更新数据库审核状态 3)更新solr已审核数 ,这时遇到一个问题,就是当用户进行批量审核的时候,这时比如有10个品被审核,那这10个请求可能会被同时打到10个机器上,然后同时执行上段代码(1,2,3步),这时就有可能出现高并发的问题,比如现在已经审核了9个商品,然后最多审核10个,两个请求同时进来,第一个请求读取到的是9,然后开始执行2和3步,结果还没执行完3,第二个请求就进来了,这时他读到的也是9(由于还没重刷solr),所以就会导致多审核了一个商品。
由于是多台机器并发问题,所以不能只用Synchroinzed这种,故这里采用分布式锁方式。
String lockKey = null; if(RoutineType.SEC_KILL.isEqual(activity.getRoutineType())){ //秒杀频道 CheckGroup group = routineCheckGroupService.getCheckGroupByErpPin(activity.getChannelID(),erpPin); if(group!=null && pageView.getRoleType()!=1 && routineCheckGroupService.isLeafCheckGroupUser(group.getId())){ //如果是末级审核组,roleType=1为运营审核 lockKey = this.acquireCheckLock(group.getId(), applyWare.getBatchId()); int allCanAssign = queryAssignedBatchResourceCount(group.getId(), applyWare.getBatchId());//查询审核组在当前批次上已分配到的资源数 int hasPassed = checkActivityService.queryHasPassedNum(Arrays.asList(group.getId()), applyWare.getBatchId()); LogTypeEnum.ROUTINE_CHECK_RECOMMEND.warn("passApply hasPassed:{}, allCanAssign:{}", hasPassed, allCanAssign); if(hasPassed + 1 > allCanAssign){ result.setSuccess(false); result.setResultCode("当前批次可审核通过"+ allCanAssign +"条,已审核通过" + hasPassed + "条,通过数量超过最大限制!"); return result; } } } this.releaseCheckLock(lockKey);//释放分布式锁
/** * 获得审核操作时的分布式锁 */ private String acquireCheckLock(final Long checkGroupId, final Long batchId) { String lockKey = "Check_Lock_" + checkGroupId + "_" + batchId; int tryTimes = 0; while(true) { //如果没获得锁,会一直循环,直到超过60次 int lockSeconds = 120;//120秒后过期, 在业务执行完成后会主动删除锁 if (redisClient.setnx(lockKey, "1") > 0) {//锁不存在,则获取锁成功 redisClient.expire(lockKey, lockSeconds); LogTypeEnum.ROUTINE_CHECK_RECOMMEND.warn("审核操作获得锁lockKey:{}, tryTimes:{}", lockKey, tryTimes); break; } tryTimes ++; try { if (redisClient.ttl(lockKey) < 0) {//防止上一操作加锁成功,但设置过期语句执行失败; [当 key 存在但没有设置剩余生存时间时,返回 -1] redisClient.expire(lockKey, 1);//迅速过期 } LogTypeEnum.ROUTINE_CHECK_RECOMMEND.warn("审核操作没有获得锁 lockKey:{}, tryTimes:{}", lockKey, tryTimes); Thread.sleep(2000);//休眠 2 秒 } catch (InterruptedException e) { } if (tryTimes > 60) { throw new RuntimeException("审核操作等待超时!"); } } return lockKey; }
/** * 释放审核操作时获得的分布式锁 */ private void releaseCheckLock(final String checkLock) { if (checkLock != null) { redisClient.del(checkLock); } }
相关推荐
Redis分布式锁实现Redisson 15问 Redis分布式锁是指在分布式系统中,多个服务实例之间对同一个资源加锁的机制,以保证数据的一致性和安全性。Redisson是一个基于Redis的分布式锁实现,它提供了一个高效、可靠的加锁...
以下是一个简单的C# Redis分布式锁实现: ```csharp public bool TryAcquireLock(string lockKey, int lockTimeout) { var redis = ConnectionMultiplexer.Connect("localhost:6379"); var db = redis.Get...
在IT行业中,尤其是在高并发的电子商务系统中,"redis分布式锁实现抢单秒杀"是一个常见的挑战。这个场景模拟了多个用户同时参与秒杀活动,系统需要确保库存的准确性和抢单的公平性,避免超卖和数据不一致的问题。...
使用命令介绍: SETNX SETNX key val 当且仅当key不存在时,set一个key为val的字符串,返回1;...为key设置一个超时时间,单位为second,超过这个时间锁会自动释放,避免死锁。 delete delete key 删除key
redis分布式锁的工具类,采用的是Lua代码的方式,保证了Java执行方法的原子性。
Redis 的高可用性和低延迟特性使其成为实现分布式锁的理想选择。下面将详细介绍如何使用 Redis 实现分布式锁以及其中可能遇到的问题和解决方案。 首先,我们需要理解分布式锁的基本概念。分布式锁是一种在分布式...
现在很多项目单机版已经不满足了,分布式变得越受欢迎,同时也带来很多问题,分布式锁也变得没那么容易实现,分享一个redis分布式锁工具类,里面的加锁采用lua脚本(脚本比较简单,采用java代码实现,无须外部调用...
redis 分布式锁实现案例和源码解析备注 * 多线程 * 使用redis事务的方法 * 加事务 乐观锁 * watch命令监控key有没有更改 * multi命令开启事务
### 基于Redis分布式锁实现“秒杀” #### 一、引言 在现代互联网应用中,“秒杀”作为一种常见的促销手段,被广泛应用于电商领域。为了保证系统的稳定性和公平性,在高并发环境下实现秒杀功能时,合理地利用分布式...
基于go语言的redis分布式锁实现项目资源
以下是一个简单的Spring Data Redis的分布式锁实现示例: ```java import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; @Component public class...
二、Redis分布式锁实现 1. 锁的创建:通常使用`SETNX`命令尝试设置一个键(如`lock_key`),如果键不存在,则设置成功,表示获取到锁。同时,为了防止死锁,可以设置一个过期时间,如`EXPIRE lock_key timeout`,...
Java基于Redis实现分布式锁代码实例 分布式锁的必要性 在多线程环境中,资源竞争是一个常见的问题。例如,在一个简单的用户操作中,一个线程修改用户状态,首先在内存中读取用户状态,然后在内存中进行修改,然后...
使用这个Redis分布式锁工具包,开发人员可以快速地在Spring项目中实现可靠的分布式锁机制,提高系统的稳定性和并发性能。 综上所述,这个压缩包提供的Redis分布式锁工具包为Java开发者提供了一种简单、高效的方法来...
Redis中的分布式锁实现通常基于`SETNX`命令或`SET`命令的`nx`与`ex`组合。`SETNX`命令用于设置键值,但如果键已经存在,则不执行任何操作,这可以确保锁的互斥性。`SET key value EX timeout NX`则同时设置了超时...
本篇文章将详细探讨如何使用Redisson实现Redis分布式事务锁,以及在Spring Boot环境中如何进行集成。 首先,Redis作为一个内存数据库,其高速读写性能使其成为实现分布式锁的理想选择。分布式锁的主要作用是在多...
Redis分布式锁实现方式及超时问题解决 本文主要介绍了Redis分布式锁实现方式及超时问题解决,通过详细的示例代码和实现原理,帮助读者理解分布式锁的应用场景和实现方式,并解决分布式锁常见的问题。 一、分布式锁...
本篇文章将深入探讨如何在C#.NET环境下利用Redis实现分布式锁,以及相关的核心知识点。 首先,让我们理解什么是分布式锁。分布式锁是在分布式系统中,用于协调不同节点间对共享资源访问的一种工具。它确保在任何...
本文将深入探讨如何使用C++结合Redis实现分布式锁,并详细讲解Redis API在C++中的应用,以及如何处理与Boost库的集成。 首先,Redis是一个高性能的键值存储数据库,广泛用于缓存、消息队列、分布式锁等场景。分布式...