分布式锁的使用

1. 将加锁的方法抽离,装载加锁的方法,相关业务写在这里面,也就是需要上锁的操作,key值通过标签传入
package com.cloud.drore.eboos.common.util;


import org.springframework.boot.autoconfigure.klock.annotation.Klock;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import javax.annotation.Resource;
import java.math.BigDecimal;
import static org.springframework.boot.autoconfigure.klock.model.LockType.Fair;


/**
 * 
 *
 * @Description: <br>
 * @Project: eboos <br>
 * @CreateDate: Created in 2018/3/23 0023 上午 11:18 <br>
 * @Author: <a href="410508961@qq.com">夏凯</a>
 */
@Component
public class RedisKeysClockUtil {

    @Resource
    JedisPoll jedisPoll;

    /**
     * @param key
     * @param money
     * @param flag
     * @ClassName: RedisKeysClockUtil
     * @Return: java.math.BigDecimal
     * @Decription: 根据key值,金额变动值,变动类型得到变动之后的资金池金额
     * @CreateDate: Created in 2018/3/23 0023 下午 2:32
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    @Klock(keys = {"{#key}"}, lockType = Fair, waitTime = 10)
    //true 加  false 减
    public BigDecimal  cashPoolChange(String key, BigDecimal money, Boolean flag) {
        JedisPool jedisPool = jedisPoll.redisPoolFactory();
        Jedis orderJedis = jedisPool.getResource();
        String beginMoney = orderJedis.get(key).toString();
        if (flag) {
            //退款,充值
            BigDecimal endMoney = new BigDecimal(beginMoney).add(money);
            orderJedis.set(key, endMoney.toString());
            return endMoney;
        } else {
            //下单
            BigDecimal endMoney = new BigDecimal(beginMoney).subtract(money);
            orderJedis.set(key, endMoney.toString());
            return endMoney;
        }
    }

    /**
     * @param key
     * @param count
     * @param flag
     * @ClassName: RedisKeysClockUtil
     * @Return: java.lang.Integer
     * @Decription: 根据key值,库存变动值,变动类型得到变动之后的库存
     * @CreateDate: Created in 2018/3/23 0023 下午 2:35
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    @Klock(keys = {"{#key}"}, lockType = Fair, waitTime = 10)
    public Integer stockChange(String key, Integer count, Boolean flag) {
        //true 加  false 减
        JedisPool jedisPool = jedisPoll.redisPoolFactory();
        Jedis orderJedis = jedisPool.getResource();
        String beginCount = orderJedis.get(key).toString();
        if (flag) {
            // 退订
            Integer endCount = Integer.parseInt(beginCount) + count;
            orderJedis.set(key, endCount.toString());
            return Integer.parseInt(beginCount) + count;
        } else {
            //下单
            Integer endCount = Integer.parseInt(beginCount) - count;
            orderJedis.set(key, endCount.toString());
            return endCount;
        }
    }
}

2.启动项修改,由于common里面的类扫描不到,需要对几个配置属性进行启动加载

package com.cloud.drore.eboss;

import com.cloud.drore.eboos.common.util.JedisPoll;
import com.cloud.drore.eboos.common.util.RedisKeysClockUtil;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.klock.KlockAutoConfiguration;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.annotation.EnableScheduling;

/**
 * @Author: wcy
 * @Description:
 * @Date: Created in 2017/12/27 13:40
 * @Modified By:
 */
@MapperScan(basePackages = {"com.cloud.drore.eboss.operation.mapper"})
@SpringBootApplication
@ServletComponentScan
@EnableDiscoveryClient
@EnableFeignClients
@EnableScheduling  //下面三个启动加载项
@Import({JedisPoll.class, RedisKeysClockUtil.class, KlockAutoConfiguration.class})
public class EbossOperationApplication {

    public static void main(String[] args) {
        SpringApplication.run(EbossOperationApplication.class, args);
    }
}
3. jedispool是获取到连接池信息
package com.cloud.drore.eboos.common.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * 浙江卓锐科技股份有限公司 版权所有  Copyright 2018<br>
 *
 * @Description: 得到redisPool<br>
 * @Project: eboos <br>
 * @CreateDate: Created in 2018/3/15 18:44 <br>
 * @Author: <a href="410508961@qq.com">夏凯</a>
 */
@Configuration
public class JedisPoll {

    @Autowired
    RedisProperties redisProperties;

    @Bean
    public JedisPool redisPoolFactory() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(redisProperties.getPool().getMaxIdle());
        jedisPoolConfig.setMaxWaitMillis(redisProperties.getPool().getMaxWait());


        JedisPool jedisPool = new JedisPool(jedisPoolConfig, redisProperties.getHost(), redisProperties.getPort(), redisProperties.getTimeout());

        return jedisPool;
    }
}  

4.kclock自动装配

klock自动装配
package org.springframework.boot.autoconfigure.klock;

import io.netty.channel.nio.NioEventLoopGroup;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.Codec;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.klock.config.KlockConfig;
import org.springframework.boot.autoconfigure.klock.core.BusinessKeyProvider;
import org.springframework.boot.autoconfigure.klock.core.KlockAspectHandler;
import org.springframework.boot.autoconfigure.klock.core.LockInfoProvider;
import org.springframework.boot.autoconfigure.klock.lock.LockFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.util.ClassUtils;

/**
 * Created by kl on 2017/12/29.
 * Content :klock自动装配
 */
@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
@EnableConfigurationProperties(KlockConfig.class)
@Import({KlockAspectHandler.class})
public class KlockAutoConfiguration {

    @Autowired
    private KlockConfig klockConfig;

    @Bean(destroyMethod = "shutdown")
    @ConditionalOnMissingBean
    RedissonClient redisson() throws Exception {
        Config config = new Config();
        if(klockConfig.getClusterServer()!=null){
            config.useClusterServers().setPassword(klockConfig.getPassword())
                    .addNodeAddress(klockConfig.getClusterServer().getNodeAddresses());
        }else {
            config.useSingleServer().setAddress(klockConfig.getAddress())
                    .setDatabase(klockConfig.getDatabase())
                    .setPassword(klockConfig.getPassword());
        }
        Codec codec=(Codec) ClassUtils.forName(klockConfig.getCodec(),ClassUtils.getDefaultClassLoader()).newInstance();
        config.setCodec(codec);
        config.setEventLoopGroup(new NioEventLoopGroup());
        return Redisson.create(config);
    }

    @Bean
    public LockInfoProvider lockInfoProvider(){
        return new LockInfoProvider();
    }

    @Bean
    public BusinessKeyProvider businessKeyProvider(){
        return new BusinessKeyProvider();
    }

    @Bean
    public LockFactory lockFactory(){
        return new LockFactory();
    }
}

5.这里是测试方法,大家可以启其他服务进行测试

package com.cloud.drore.eboss.operation.controller;

import com.cloud.drore.eboos.common.base.ResultMessage;
import com.cloud.drore.eboss.operation.service.impl.DistributedLockServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 *
 *
 * @Description: 分布式锁测试接口<br>
 * @Project: eboos <br>
 * @CreateDate: Created in 2018/1/6 0006 下午 5:45 <br>
 * @Author: <a href="410508961@qq.com">夏凯</a>
 */
@RestController
@RequestMapping("/lock")
@Api(value = "/分布式锁接口", description = "分布式锁测试接口-夏凯")
public class DistributedLockTestController {
    @Resource
    DistributedLockServiceImpl distributedLockServiceImpl;
    @ApiOperation(value = "分布式锁测试接口)")
    @PostMapping(value = "/test")
    public ResultMessage test() {
        return distributedLockServiceImpl.testDistributedLock();
    }
}

6.然后这里给下标签的相关说明,可以在方法里面传入

package org.springframework.boot.autoconfigure.klock.annotation;

import org.springframework.boot.autoconfigure.klock.model.LockType;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by kl on 2017/12/29.
 * Content :加锁注解
 */
@Target(value = {ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Klock {
    /**
     * 锁的名称
     * @return
     */
    String name() default "";
    /**
     * 锁类型,默认可重入锁
     * @return
     */
    LockType lockType() default LockType.Reentrant;
    /**
     * 尝试加锁,最多等待时间
     * @return
     */
    long waitTime() default Long.MIN_VALUE;
    /**
     *上锁以后xxx秒自动解锁
     * @return
     */
    long leaseTime() default Long.MIN_VALUE;

    /**
     * 自定义业务key
     * @return
     */
     String [] keys() default {};
}

7.输入swagger地址:http://localhost:2005/swagger-ui.html#/

8.最后一定要配置完参数才能进行操作啊!否则可能会启动报错,希望能帮到大家

9.本文地址:https://blog.csdn.net/qq_34754038/article/details/79677679

最后贴下git的地址,欢迎留言







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Redisson是一个基于Redis实现的Java驻内存数据网格(In-Memory Data Grid)和分布式锁(Distributed Lock)框架,它提供了一系列的分布式数据结构,其中包括分布式锁的实现。 使用Redisson实现分布式锁非常简单,只需要遵循以下步骤: 1. 引入Redisson的依赖包: ```xml <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.12.6</version> </dependency> ``` 2. 创建Redisson客户端对象: ```java Config config = new Config(); config.useSingleServer().setAddress("redis://127.0.0.1:6379"); RedissonClient redisson = Redisson.create(config); ``` 3. 获取锁对象: ```java RLock lock = redisson.getLock("myLock"); ``` 4. 加锁: ```java lock.lock(); ``` 5. 执行业务逻辑: ```java try { // 执行业务逻辑 } finally { // 释放锁 lock.unlock(); } ``` 完整的示例代码如下: ```java public class MyService { private RedissonClient redisson; public MyService() { Config config = new Config(); config.useSingleServer().setAddress("redis://127.0.0.1:6379"); redisson = Redisson.create(config); } public void myMethod() { RLock lock = redisson.getLock("myLock"); try { lock.lock(); // 执行业务逻辑 } finally { lock.unlock(); } } } ``` 需要注意的是,在执行业务逻辑的过程中,一定要放在try...finally块中,并在finally块中释放锁,以确保在出现异常时锁能够正确地被释放。 ### 回答2: Redisson是一种基于Redis实现的分布式锁框架。以下是Redisson分布式锁使用说明: 1. 引入Redisson依赖:首先需要在项目中引入Redisson的依赖,可以通过Maven或者Gradle等构建工具来管理依赖。 2. 创建RedissonClient:使用RedissonClient可以连接到Redis服务器,并获取一个分布式锁对象。 3. 加锁:使用分布式锁对象可以通过lock()方法来获取锁,该方法默认的锁超时时间是30秒,超过该时间锁会自动释放。也可以使用自定义的锁超时时间。 4. 解锁:在加锁的代码块执行完毕后,需要调用unlock()方法手动释放锁,确保锁的释放,避免死锁的产生。 5. 锁的可重入性:Redisson的分布式锁支持可重入性,即同一个线程可以多次获取同一个锁,在释放锁的时候需要调用相应次数的unlock()方法来释放锁。 6. 锁的异步执行:Redisson的分布式锁也支持异步执行,即lock()方法可以通过异步方式获取锁。 7. 锁的公平性:Redisson的分布式锁可以选择是否公平锁,默认为非公平锁,即不保障获取锁的顺序。可以通过配置参数来设置公平锁。 8. 锁监控:Redisson提供了监控分布式锁的功能,可以通过调用getLock("/lock")方法来监控名为"lock"的锁的情况。 总结来说,Redisson分布式锁使用非常简单,只需要引入依赖、创建客户端、加锁和解锁即可。同时,Redisson还提供了可重入性、异步执行、公平锁和锁监控等功能,可以根据实际需求进行配置和使用。通过使用Redisson分布式锁,可以有效地控制多线程环境下共享资源的访问,避免数据不一致和竞态条件的发生。 ### 回答3: Redisson是一个基于Redis的Java实现,提供了一系列分布式相关的功能,其中包括分布式锁使用使用Redisson实现分布式锁,首先需要创建一个RedissonClient实例,通过该实例可以获取一个RLock对象,RLock提供了加锁和释放锁的方法。 在加锁方面,Redisson支持公平锁和非公平锁。公平锁会按照请求的顺序依次加锁,而非公平锁则允许插队,谁先抢到锁就谁先执行。通过调用RLock对象的lock()方法可以获取锁,该方法会一直阻塞直到获取到锁为止。如果不希望一直阻塞,可以使用tryLock()方法,该方法会尝试获取锁一段时间,如果超过指定的等待时间仍未获取到锁,则返回false。 在释放锁方面,可以使用unlock()方法来释放锁,只有加锁方才能释放锁。可以通过判断当前线程是否持有锁,再决定是否释放锁。 使用Redisson的分布式锁还有一些其他的特性,比如锁的自动续约、可重入锁、可中断锁等,这些特性都可以通过相应的方法来使用。 总的来说,Redisson的分布式锁使用起来非常方便,只需要简单的几行代码就可以实现分布式环境下的锁功能。但需要注意的是,在使用分布式锁时要考虑并发情况、死锁问题以及锁的粒度等,以确保代码的正确性和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值