分布式锁实现方式

分布式锁的类型

mysql实现分布式锁

1.数据库建立锁表

数据库属性:
主键,方法名入参,主机信息线程名字(保证)。备注。(方法名入参建立唯一性索引)
实现方式:当需要锁定方法时,将方法名和入参insert进去即可,解锁时删除该条记录即可。

弊端:
1.不能作为阻塞锁来使用。
2.锁没有失效时间,删除锁出现问题的时候,其他线程无法获取锁,这个方法将会一直锁住。
3.数据库作为单点系统,当出现问题的时候,导致整个系统出现不可运行。

弊端解决方案:
1.不能作为阻塞锁来使用:加锁里面做一个while循环获得锁再跳出
2.锁没有失效时间:做定时任务。
3.数据库单点不可靠:做主备,服务降级等。

2.数据库建立排他锁

数据库属性:
主键,方法名入参,主机信息线程名字(保证),备注。(方法名入参建立唯一性索引)
实现方式:利用数据库的排他锁实现分布锁,加锁:select * from method_lock where method =xx for update(自动提交关闭)
解锁:connection.commit();

这样就比较优雅的解决了阻塞问题,判断是否有这条记录,有的话继续等待,或者出现问题的话处于一直阻塞的状态,成功的话就直接返回了,完事解锁就成
会出现的问题:
1.当数据量比较小的时候,数据库的执行策略判断全表扫描会比走索引快时候,这是就不是行级锁了,而是走表级锁了,这时就出现的问题就大了,所有他有一定风险。
2.但一直没执行解锁操作的时候线程就一直占用着connection,然后数据库连接数局满了。

缓存实现分布式锁

使用redis实现分布式锁

使用redis实现分布式锁是一个比较大家用到比较多的方式
实现方式:使用jedis来向redis里面set数据:具体参数,key(唯一性的代表锁),requestId(value放请求Id,这样能保证开锁解锁都是同一个人),加锁逻辑是,当key不存在时,才进行set操作,若key已经存在,则不做任何操作。同时set过期时间,这里需要注意的是set数据可set过期时间是同一个操作,防止set完数据出现程序崩溃产生死锁问题。
解锁:为了用key获取value查看request是否一致,一致则解锁,但是查询,对比,删除锁,这一些为了保证原子信记得加事务。

不好的地方:过期时间时间不好控制,容易出现垃圾锁的问题或者锁解了事务还没完。
好的地方:性能好,搭建简单。

zk实现分布式锁

使用zookeeper实现分布式锁

由于自己本身没有使用过zk实现分布式锁,这里看到一个百家号写的比较好,给上链接。
https://baijiahao.baidu.com/s?id=1593258103626631655&wfr=spider&for=pc

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值