一键搞懂分布式锁1

什么是分布式锁?

在弄懂分布式锁之前,我们先搞懂分布式锁最终期望是什么?
在我所了解的是:与多线程一样,保证数据的一致性

那么来了,分布式锁和多线程什么关系?
若在同一个JVM的前提下,就没必要知道分布式锁是个什么东西,因为在一个JVM下变量是共享的,锁的也是同一个东西,所以加锁或者关键词等等方法可以保证线程的安全。那么不在同一个JVM的前提下,变量也不共享,不能保证我们操作的是一个东西,这就需要借助外界资源,比如关系型数据库:MySql、Oracle,非关系型数据库:Redis,以及Zookeeper等等。我个人认为是这样:只要我能保证这个方法不管在哪个系统中,大环境下是串行的,一个完了再一个即可!

分布式锁-基于数据库方面实现

网上的资源很多,这篇文章我们先从数据库层面进行实现我们分布式锁。

从上面我们了解到,不管在哪个系统上,我们给对象、变量加的都是同一个,此时这个同一个在数据库里应该是唯一约束,只允许出现一次,那么就保证了不管哪个系统操作的都是同一个,剩下的操作需要在我们业务层进行实现。

此时的需求就是:需要一张表用来存我们的信息,以及对应的业务是唯一约束。我们给方法加锁就行。

CREATE TABLE `method_locks` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `method_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '方法名',
  `messages` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '项目以及线程名等等信息',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `method_names` (`method_name`) USING BTREE COMMENT '唯一约束'
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;

接下来就需要我们在页面方面处理,具体如下:
利用以前学习Spring Cloud中的资源进行演示:
将服务注册在Eureka集群中:在这里插入图片描述
目前Eureka出过文章,若不了解的话,请参考文章

通过OpenFeign+Ribbon将请求分发在我们所需要的系统上:
在这里插入图片描述
目前Ribbon出过文章,若不了解的话,请参考文章。OpenFeign不了解的话,后续出文章进行简单介绍一下。

具体将要执行的业务程序order8002、order8003
在这里插入图片描述
具体看看此时业务是怎么写的,此处是重点,以8002项目为例:

 @RequestMapping("/getMyStaff")
    public Staff getMyStaff(@RequestParam("staffIdNo") String staffIdNo){
        System.out.println("getMyStaff()方法进入:8002........");
        // 数据库入参
        MethodLocks methodLocks = new MethodLocks();
        methodLocks.setMethodName(Thread.currentThread().getStackTrace()[1].getMethodName());
        methodLocks.setMessages("8002服务器上的方法被锁定,正在执行....");
        Staff staff = null;
        try {
            methodLocksService.inMethodLocks(methodLocks);
            // 具体执行的业务
               Thread.sleep(10000);
               methodLocksService.deMethodLocks(methodLocks.getMethodName());
        } catch (Exception e) {
            e.printStackTrace();
            //当前方法已经被锁定,无法访问
            while (true){
                MethodLocks methodLocks1 = methodLocksService.getMethodLocks(Thread.currentThread()
                        .getStackTrace()[1].getMethodName());
           		System.out.println("此时的数据为MethodLocks:" + methodLocks1);
       			System.out.println("等待执行以下方法:"+System.currentTimeMillis());
                if (methodLocks1 == null){
                    methodLocksService.inMethodLocks(methodLocks);
                    break;
                }
            }
            // 具体执行的业务
            Thread.sleep(10000);
            methodLocksService.deMethodLocks(methodLocks.getMethodName());
        }
        return staff;
    }

此时访问8002正在进行业务处理:
在这里插入图片描述
那么此时的8003肯定在等待状态:
在这里插入图片描述
在这里插入图片描述
符合我们预期的期望结果顺序,这个就是模拟的基于数据库方面的分布式锁。

不过最好不要采用此种方案进行分布式锁的处理,消耗大量的资源,影响项目效率!

分布式锁-基于Redis方面实现

请参考下一篇文章

分布式锁-基于Redisson方面实现

请参考下一篇文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胤墨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值