分布式锁之数据库锁
来源:互联网 发布:qq邮箱smtp设置 端口25 编辑:程序博客网 时间:2024/06/12 00:38
在分布式环境下经常会出现这样的需求,多个服务器节点调用远程服务器的某项资源,但是这样的资源在同一时间点只允许一个服务器节点使用,类似于这样机器与机器之间的并发无法通过传统java并发API来解决.于是便有了分布式锁
数据库锁是并发锁的一种实现
分布式锁需要满足以下两个条件
- 在分布式环境下,在同一时间只能被一台机器的一个线程执行
- 为了避免死锁,分布式锁是一把可重入锁
- 锁的获取和释放必须高性能
CREATE TABLE `resource_lock` ( `id` int(11) NOT NULL AUTO_INCREMENT `resource_name` varchar(64) NOT NULL , `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '保存数据时间,自动生成', `holder_info` varchar(64) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uidx_resource` (`resource_name`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT '资源锁表';
锁表的关键点在于唯一索引 UNIQUE KEY,这一条件保证了在任何时候每个资源只能有一个主机能够获取该资源.而holder_info记录了获取资源的是谁,这个字段使分布式锁支持可重入性,从而避免了死锁
如果我们锁住某个资源资源的时候,我们首先获取资源,获取资源的方法是在该表中添加一个资源,如果添加成功,则获取资源成功,反之失败
这个分布式锁仍然存在如下问题:
1.数据库必须是集群状态,若是单点数据库,一旦数据库瘫痪,整个系统都将处于不可用状态
2.如果某台主机获取了该锁,但是因为意外情况宕机,导致该资源一直处于占用状态.所以需要在应用层加上定时task,根据updateTime清除到时但是没有被释放的锁
如果我们需要该锁支持阻塞,也就是当节点没有获取到锁的时候就等待,直到获取锁,我们在插入数据(也就是获取锁)失败的情况下,使用mysql悲观锁锁定该锁,mysql代码如下
-- 获取锁代码如下begin;select * from resource_lock where resource_name='resource' for update
-- 业务逻辑dosomething()
-- 释放锁代码如下commit;
该方法有几个注意点:
1.务必对resource_name添加索引,否则mysql将会锁全表,这会造成其它线程都无法申请锁
2.其它线程等待获取锁的时候阻塞时间是有限制的,超时后mysql会报如下的错误
insert into resource_lock values(1,'resource',current_timestamp,'holder_info');
lock wait time可以自己更改mysql配置
3.我们要使用排它锁进行分布式锁的lock,如果一个排他锁不提交,会长时间占用数据库连接池连接,如果这样的连接变多,可能会造成其它线程获取mysql连接失败
基于数据库的分布式锁优缺点分析
优点:
1.直接借助数据库容易理解
2.数据库锁具有持久化特性
缺点
1.操作数据库会有性能开销
2.数据库阻塞锁的实现可能会造成占用大量数据库连接池连接导致其它线程无连接可用
- 分布式锁之数据库锁
- 分布式锁-基于数据库实现
- Zookeeper之分布式锁
- 分布式环境必备技能之分布式锁
- 分布式锁方式(一、基于数据库的分布式锁)
- Zookeeper实战之分布式锁
- 基于数据库的分布式锁实现
- Apace实时数据库之分布式集中控制
- MapReduce和分布式数据库之争
- 大型电子商务架构之-分布式数据库架构
- 计算机英语之分布式数据库系统
- 计算机英语之分布式数据库系统(2)
- 计算机英语之分布式数据库系统
- 计算机英语之分布式数据库系统
- 吴治辉:分布式数据库MyCAT之前世今生
- 高一致性分布式数据库系统之实现
- 8-hadoop之hbase分布式数据库
- 高一致性分布式数据库系统之实现
- 综合变换
- [ArcGIS] 焦点统计应用 提取山顶点 地形起伏度
- bzoj3674 可持久化并查集加强版 (主席树 & 并查集)
- 自定义类型部分知识写一篇博客。 知识点: >结构体类型创建 >结构体初始化 >结构体内存对齐 >位段,位段计算机大小。 >枚举+联合。
- TensorFlow学习笔记1:Hello TensorFlow!
- 分布式锁之数据库锁
- LeetCode 300. Longest Increasing Subsequence
- 透视投影
- 6分钟掌握草根seo必学的优化教程
- 彻底删除Ubuntu EFI分区及启动项
- javascript+html+css简单的实现复选框的全选与单选
- 相机1
- Python-set
- 利用人工智能进行网页设计的10种方法