ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

分布式锁

2021-10-27 18:31:58  阅读:224  来源: 互联网

标签:加锁 name lock distributed key 节点 分布式



1,基于数据库表实现
机制:在数据库中创建一个表,表中包含方法名等字段,并在方法名字段上创建唯一索引,想要执行某个方法,就使用这个方法名向表中插入数据,成功插入则获取锁,执行完成后删除对应的行数据释放锁。
1,首先创建一个 分布式锁表
DROP TABLE IF EXISTS `distributed_lock`;
CREATE TABLE `distributed_lock` (
`distributed_lock_id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`method_name` VARCHAR(64) NOT NULL COMMENT '加锁的方法名',
`distributed_lock_desc` VARCHAR(255) NOT NULL COMMENT '备注',
`inserted_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`distributed_lock_id`),
UNIQUE KEY `unique_key_method_name` (`method_name`) USING BTREE
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='分布式锁';

2,将要执行的方法名作为参数,保存到分布式锁表中

INSERT INTO distributed_lock (distributed_lock_id,method_name, distributed_lock_desc) VALUES (816374617763712,'要加锁的方法名称', '描述信息');

如果可以插入成功,代表获得了锁,可以执行操作;逻辑执行完毕后,删除数据,释放锁

DELETE FROM distributed_lock WHERE method_name ='要释放锁的方法名称';

缺点:

1,需要考虑数据的性能以及保证数据库高可用 

2,不具备可重入的特性

3,如果宕机,会造成死锁

4,获取不到锁,直接返回失败,需要代码做循环获取锁

2,基于Redis实现(redis,redission,redLock,lua脚本,看门狗机制)
机制:jedis.set(String key, String value, String nx, String px, int time);
参数说明:
key:锁,保证唯一
value:竞争者的ID,例如线程名,释放锁的时候需要判断释放者是否未该锁的持有者
nx:SET IF NOT EXIST,即当key不存在时进行set操作;当key已存在则不做任何操作。
px:表示要给当前的锁设置一个过期时间,防止死锁
time:key的过期时间
执行set()方法只有两种结果:

  1.当key不存在(没有锁),进行加锁操作,并对锁设置一个过期时间,同时value为加锁的线程名。

  2.已经有锁存在,不做任何操作。

解锁:
  1. 判断当前解锁竞争者的线程名是否为锁的持有者,如果不是直接返回失败,如果是则进入第2步。
  2. 删除key,如果删除成功,返回解锁成功,否则解锁失败。
缺点:
1,死锁问题
2,不可重入
3,因为设置了过期时间,如果业务执行时间超过过期时间,会自动释放锁
4,需要保证redis的高可用
3,基于Zookeeper实现
机制:利用Zookeeper创建临时有序节点来实现分布式锁
  1. 当客户端来请求时,在锁空间下面创建一个临时有序节点。
  2. 如果当前节点的排序是这个空间下面最小的,则代表加锁成功,否则加锁失败,加锁失败后设置Watcher,等待前面节点的通知。
  3. 当前节点监听其前面一个节点,如果前面一个节点删除了就通知当前节点。
  4. 当解锁时当前节点通知其后继节点,并删除当前节点。
缺点:
需要保证zk的高可用





标签:加锁,name,lock,distributed,key,节点,分布式
来源: https://www.cnblogs.com/chauvet/p/15472379.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有