700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > java B2B2C 源码 多级分销Springboot多租户电子商城系统-springcloud项目redis分布式锁...

java B2B2C 源码 多级分销Springboot多租户电子商城系统-springcloud项目redis分布式锁...

时间:2020-03-29 15:17:04

相关推荐

java B2B2C 源码 多级分销Springboot多租户电子商城系统-springcloud项目redis分布式锁...

在springcloud项目开发中redis分布式锁使用主要有两个场景

需要JAVA Spring Cloud大型企业分布式微服务云构建的B2B2C电子商务平台源码请加企鹅求求 :二一四七七七五六三三

1.订单重复提交或支付提交等,防止刷单 2.对某个业务进行锁定,例如:当用户同一时间,进行对账户充值和提现操作,那么这里需要根据用户ID对账户进行锁定,只有一个完成了才可以进行第二个。 开发实现方式 1.pom.xml中引入jar包,最好引入到基础模块中,其他模块通用

<!-- redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>复制代码

创建redis操作类RedisGlobalLock(自定义) redis提供RedisTemplate方法 redis提供三个方法: (1)lock 获取锁并锁定 本方法是立即获取锁状态,如果获取成功并锁定,如果获取失败 (2)tryLock 尝试获取锁并锁定 本方式是在指定时间尝试获取锁 (3)unlock 释放锁 当业务处理完毕必须释放锁 重点: lock和tryLock区别:lock是实时获取,tryLock是尝试在一段时间内一直在获取

@Servicepublic class RedisGlobalLock {private static Log log = LogFactory.getLog(RedisGlobalLock.class);private static final String TYPE_NAME = RedisGlobalLock.class.getTypeName();/** 默认30ms尝试一次 */private final static long LOCK_TRY_INTERVAL = 30L;/** 默认尝试20s */private final static long LOCK_TRY_TIMEOUT= 20 * 1000L;/** 单个业务持有锁的时间30s,防止死锁 */private final static long LOCK_EXPIRE= 30 * 1000L;@Autowiredprivate RedisTemplate<String, Object> redisTemplate;/*** 获取锁* @param key 锁Key* @return是否获取锁*/public boolean lock(String key) {return getLock(key, 0, LOCK_EXPIRE, TimeUnit.MILLISECONDS);}/*** 获取锁* @param key 锁Key* @param expire有效期* @param expireUnit 有效期时间单位* @return是否获取锁*/public boolean lock(String key, long expire, TimeUnit expireUnit) {return getLock(key, 0, expire, expireUnit);}/*** 尝试获取锁* @param key锁Key* @return 是否获取锁*/public boolean tryLock(String key) {return tryLock(key, LOCK_TRY_TIMEOUT, TimeUnit.MILLISECONDS);}/*** 尝试获取锁* @param key锁Key* @param timeout 等待超时时间* @param unit 等待超时时间单位* @return 是否获取锁*/public boolean tryLock(String key, long timeout, TimeUnit unit) {// 超时时间转成毫秒timeout = TimeUnit.MILLISECONDS.convert(timeout, unit);return getLock(key,timeout, LOCK_EXPIRE, TimeUnit.MILLISECONDS);}/*** 尝试获取锁* @param key 锁Key* @param timeout等待超时时间* @param timeoutUnit 等待超时时间单位* @param expire有效期* @param expireUnit 有效期时间单位* @return*/public boolean tryLock(String key, long timeout, TimeUnit timeoutUnit, long expire, TimeUnit expireUnit) {// 超时时间转成毫秒timeout = TimeUnit.MILLISECONDS.convert(timeout, timeoutUnit);return getLock(key,timeout, expire, expireUnit);}/*** 释放锁* @param key 锁Key*/public void unlock(String key) {key = getPrefix(TYPE_NAME) + key;Long oldExpireTime = (Long) redisTemplate.opsForValue().get(key);if(null != oldExpireTime && oldExpireTime >= System.currentTimeMillis()) {// 大于过期时间,则删除keyredisTemplate.delete(key);}}/*** 获取锁* @param key锁键值* @param timeout 超时时间* @param time 全局锁生命周期* @param unit 时间单位* @return 是否获取到锁*/private boolean getLock(String key, long timeout, long time, TimeUnit unit) {key = getPrefix(TYPE_NAME) + key;try {long startTimeMillis = System.currentTimeMillis();do {long newValue = System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(time, unit);Boolean isOk = redisTemplate.opsForValue().setIfAbsent(key, newValue);if(isOk) {// 获得锁redisTemplate.expire(key, time, unit);return true;}// 获取过期时间Long oldExpireTime = (Long) redisTemplate.opsForValue().get(key);if(null == oldExpireTime) {oldExpireTime = 0L;}if(oldExpireTime >= System.currentTimeMillis()) {// 不小于系统时间并且过了超时时间,则不获取锁if((System.currentTimeMillis() - startTimeMillis) > timeout) {return false;}// 休眠Thread.sleep(LOCK_TRY_INTERVAL);}// 新的过期时间long newExpireTime = System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(time, unit);Long currentExpireTime = (Long) redisTemplate.opsForValue().getAndSet(key, newExpireTime);if(null == currentExpireTime) {currentExpireTime = 0L;}if(currentExpireTime.equals(oldExpireTime)) {// 获取到锁redisTemplate.expire(key, time, unit);return true;}} while (true);} catch (Exception e) {return false;}}/*** 获取缓存标识前缀* @param typeName 类名* @return 前缀*/protected final String getPrefix(String typeName) {return typeName;}}复制代码

在业务逻辑层引入redis操作类

@Resourceprivate RedisGlobalLock redisGlobalLock;// 1、获取分布式锁防止重复调用 =====================================================String key = PayDistributePrefix.PAY_MEMBER_ACCOUNT + memberId;if(redisGlobalLock.lock(key)) {try{System.out.println("--处理业务---");}catch (Exception e){throw e;}finally {// 4、释放分布式锁 ================================================================redisGlobalLock.unlock(key);}}else{// 如果没有获取锁Ensure.that(true).isTrue("17000706");}复制代码

所有锁业务必须释放锁,防止死锁

Java B2B2C多用户商城 springcloud架构

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。