一种基于数据库实现分布式锁的方法与流程

文档序号:23709294发布日期:2021-01-23 16:05阅读:90来源:国知局
一种基于数据库实现分布式锁的方法与流程

[0001]
本发明涉及分布式锁技术领域,具体为一种基于数据库实现分布式锁的方法。


背景技术:

[0002]
众所周知,为了保证一个方法在高并发情况下的同一时间只能被同一个线程执行,在传统单体应用单机部署的情况下,可以使用java并发处理相关的api(如reentrantlcok或synchronized)进行互斥控制。但是,随着业务发展的需要,原单体单机部署的系统被演化成分布式系统后,由于分布式系统多线程、多进程并且分布在不同机器上,这将使原单机部署情况下的并发控制锁策略失效,为了解决这个问题就需要一种跨jvm的互斥机制来控制共享资源的访问,这就是分布式锁要解决的问题,现有的分布式锁分依赖中间件,不具备快速移植能力,导致程序运行缓慢,同时,实现方式复杂,代码繁琐,需要多个层级之间相互调用,时间消耗较大,对内存运行造成极大的压力,为此,提出一种基于数据库实现分布式锁的方法。


技术实现要素:

[0003]
(一)解决的技术问题
[0004]
针对现有技术的不足,本发明提供了一种基于数据库实现分布式锁的方法。
[0005]
(二)技术方案
[0006]
为实现上述目的,本发明提供如下技术方案:一种基于数据库实现分布式锁的方法,包括以下步骤:
[0007]
s1、查询数据库,在数据库表格中查询是否存在分布式锁;
[0008]
s2、如果数据库不存在分布式锁,则建立一个分布式锁的表格,同时添加分布式锁的执行sql语句,在进行任务操作时,将带有分布式锁的方法当做参数带入任务的方法执行方法操作,如果数据库存在分布式锁,则不建立;
[0009]
s3、添加事务日志,在操作过程中调用事务方法,及时记录操作步骤,增加网络安全性和任务执行的监控;
[0010]
s4、当线程执行完这个方法后,需要释放锁,即编写删除语句,将带有执行分布式锁编号的数据删除,从而将锁释放;
[0011]
s5、添加定时任务,定时清理线程缓存,避免解锁失败导致其他线程一直无法获取分布式锁。
[0012]
优选的,在所述s2中,所述分布式锁的表格应至少包含主键、锁定的方法名称、锁定的信息和编号等基本字段,其中,主键、锁定的方法名称要添加唯一性约束,一个方法只能存在一条记录,如果有多条请求同时提交,最终也只会生效一条,即操作成功的那个线程即获得了该方法的锁。
[0013]
在前述方案的基础上,在所述s1中,所述数据库可以为mysql、redis或zookeeper等常用数据库。
[0014]
在前述方案的基础上,在所述s2中,如果数据库存在分布式锁,则判断已存在的分布式锁心跳是否正常,如果心跳正常,说明锁被其他拥有者占用,则直接退出处理,如果锁刷新超时,心跳失常,则更新锁拥有者id、锁状态、锁维护时间,同时刷新内存中分布式锁信息,然后开始具体任务处理。
[0015]
进一步的,在所述s2中,调用分布式锁执行方法时,在方法外围添加for循环或while循环之类循环方法,直至insert成功再返回。
[0016]
进一步的,在所述s3中,在事务日志触发后,分布式锁状态刷新后台线程,轮询获取待刷新分布式锁队列中的锁对象,检查锁状态,如果状态为待解除,则删除数据库中相应的锁记录,如果锁状态正常,则更新数据库中锁维护时间,同时刷新内存中锁的心跳时间,以维持锁的继续使用。
[0017]
进一步的,在所述s4中,在释放锁之后,需添加事务日志,将执行步骤添加记录。
[0018]
进一步的,在s5中,操作结束后,调用唤醒的方法,将其他排队的线程唤醒,避免其他线程一直沉睡排队。
[0019]
(三)有益效果
[0020]
与现有技术相比,本发明提供了一种基于数据库实现分布式锁的方法,具备以下有益效果:本方法实现的分布式锁不过分依赖中间件,利用分布式锁调用方法,类似调用接口的使用,使得本方法具备快速移植能力,同时,可以适用于不同类型的关系型数据库运行,利用事务日志和定时任务及时清理缓存和解锁,减少占用资源,不存在引起数据库资源使用过高的风险。
附图说明
[0021]
图1为本发明的方法流程图。
具体实施方式
[0022]
下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
[0023]
实施例
[0024]
请参阅图1,本发明提供一种技术方案:一种基于数据库实现分布式锁的方法,包括以下步骤:
[0025]
s1、查询数据库,在数据库表格中查询是否存在分布式锁;
[0026]
s2、如果数据库不存在分布式锁,则建立一个分布式锁的表格,同时添加分布式锁的执行sql语句,在进行任务操作时,将带有分布式锁的方法当做参数带入任务的方法执行方法操作,如果数据库存在分布式锁,则不建立;
[0027]
s3、添加事务日志,在操作过程中调用事务方法,及时记录操作步骤,增加网络安全性和任务执行的监控;
[0028]
s4、当线程执行完这个方法后,需要释放锁,即编写删除语句,将带有执行分布式锁编号的数据删除,从而将锁释放;
[0029]
s5、添加定时任务,定时清理线程缓存,避免解锁失败导致其他线程一直无法获取分布式锁。
[0030]
本实施例中,具体的:在s2中,分布式锁的表格应至少包含主键、锁定的方法名称、锁定的信息和编号等基本字段,其中,主键、锁定的方法名称要添加唯一性约束,一个方法只能存在一条记录,如果有多条请求同时提交,最终也只会生效一条,即操作成功的那个线程即获得了该方法的锁;将主键、锁定的方法名称要添加唯一性约束,可以确保数据的唯一性,避免出现具有冲突和带有歧义的数据,使得每条数据都是一条完整独立的数据。
[0031]
本实施例中,具体的:在s1中,数据库可以为mysql、redis或zookeeper等常用数据库;mysql是最流行的关系型数据库管理系统,在web应用方面mysql是最好的rdbms应用软件之一,redis用于存放缓存数据,一些常用的热点信息存放在redis里面的话,就不需要去数据库中获取了,可以提高程序的运行效率,减少数据库的查找,提高代码的运行效率,但是,数据是临时的,不能直接改变数据库内部的内容,需要进行数据的转换才能最终更改数据库的内部,zookeeper跟chubby一样用来存放一些相互协作的信息(coordination),这些信息比较小一般不会超过1m,在zookeeper中是以一种hierarchicaltree的形式来存放,这些具体的key/value信息就store在treenode中,当有事件导致node数据,例如:变更,增加,删除时,zookeeper就会调用triggerwatch方法,判断当前的path来是否有对应的监听者(watcher),如果有watcher,会触发其process方法,执行process方法中的业务逻辑。
[0032]
本实施例中,具体的:在s2中,如果数据库存在分布式锁,则判断已存在的分布式锁心跳是否正常,如果心跳正常,说明锁被其他拥有者占用,则直接退出处理,如果锁刷新超时,心跳失常,则更新锁拥有者id、锁状态、锁维护时间,同时刷新内存中分布式锁信息,然后开始具体任务处理;判断分布式锁心跳是否正常,因为分布式锁具有互斥性,在分布式系统环境下,只有一个客户端能持有锁;分布式锁互斥性,在分布式系统环境下,只有一个客户端能持有锁,高性能的获取锁与释放锁,分布式锁具备可重入特性,同一线程在未释放锁时如果再次申请锁资源不需要走申请流程,只需要将已经获取的锁继续返回并且记录上已经重入的次数即可,分布式锁具备锁失效机制,防止死锁,即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁。
[0033]
前述方案的基础上:在s2中,调用分布式锁执行方法时,在方法外围添加for循环或while循环之类循环方法,直至insert成功再返回;以为分布式锁是非阻塞的,因为插入数据失败之后会直接报错,想要获得锁就需要再次操作,而for循环或while循环之类循环方法是比较常用的循环方法,简单、高效。
[0034]
本实施例中,具体的:在s3中,在事务日志触发后,分布式锁状态刷新后台线程,轮询获取待刷新分布式锁队列中的锁对象,检查锁状态,如果状态为待解除,则删除数据库中相应的锁记录,如果锁状态正常,则更新数据库中锁维护时间,同时刷新内存中锁的心跳时间,以维持锁的继续使用;可以根据用户的操作选择性的给予延长线程失效或关闭线程。
[0035]
前述方案的基础上:在s4中,在释放锁之后,需添加事务日志,将执行步骤添加记录;事务日志文件transactionlogfile是用来记录数据库更新情况的文件,扩展名为baildf。在sqlserver7.0和sqlserver2000中,如果设置了自动增长功能,事务日志文件将会自动扩展。一般情况下,在能够容纳两次事务日志截断之间发生的最大数量的事务时,事务日志的大小是稳定的,事务日志截断由检查点或者事务日志备份触发。
[0036]
进一步的:在s5中,操作结束后,调用唤醒的方法,将其他排队的线程唤醒,避免其他线程一直沉睡排队;通用唤醒的方法,可以减少其他线程等待时间,避免网络资源浪费。
[0037]
综上,该一种基于数据库实现分布式锁的方法的工作原理和工作过程为,在使用时,首先需要检查数据库是否存在分布式锁,如果数据库不存在分布式锁,则建立一个分布式锁的表格,分布式锁的表格应至少包含主键、锁定的方法名称、锁定的信息和编号等基本字段,其中,主键、锁定的方法名称要添加唯一性约束,一个方法只能存在一条记录,如果有多条请求同时提交,最终也只会生效一条,即操作成功的那个线程即获得了该方法的锁,同时添加分布式锁的执行sql语句,在进行任务操作时,将带有分布式锁的方法当做参数带入任务的方法执行方法操作,调用分布式锁执行方法时,在方法外围添加for循环或while循环之类循环方法,直至insert成功再返回;以为分布式锁是非阻塞的,因为插入数据失败之后会直接报错,想要获得锁就需要再次操作,而for循环或while循环之类循环方法是比较常用的循环方法,简单、高效,如果数据库存在分布式锁,则判断已存在的分布式锁心跳是否正常,如果心跳正常,说明锁被其他拥有者占用,则直接退出处理,如果锁刷新超时,心跳失常,则更新锁拥有者id、锁状态、锁维护时间,同时刷新内存中分布式锁信息,然后开始具体任务处理,在进行分布式锁操作过程中,要添加事务日志,在操作过程中调用事务方法,及时记录操作步骤,增加网络安全性和任务执行的监控,在事务日志触发后,分布式锁状态刷新后台线程,轮询获取待刷新分布式锁队列中的锁对象,检查锁状态,如果状态为待解除,则删除数据库中相应的锁记录,如果锁状态正常,则更新数据库中锁维护时间,同时刷新内存中锁的心跳时间,以维持锁的继续使用,判断分布式锁心跳是否正常,因为分布式锁具有互斥性,在分布式系统环境下,只有一个客户端能持有锁;分布式锁互斥性,在分布式系统环境下,只有一个客户端能持有锁,高性能的获取锁与释放锁,分布式锁具备可重入特性,同一线程在未释放锁时如果再次申请锁资源不需要走申请流程,只需要将已经获取的锁继续返回并且记录上已经重入的次数即可,分布式锁具备锁失效机制,防止死锁,即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁,在分布式锁使用完毕后,要及时解锁,避免占用线程,添加定时任务,定时清理线程缓存,避免解锁失败导致其他线程一直无法获取分布式锁,操作结束后,调用唤醒的方法,将其他排队的线程唤醒,避免其他线程一直沉睡排队,本方法实现的分布式锁不过分依赖中间件,利用分布式锁调用方法,类似调用接口的使用,使得本方法具备快速移植能力,同时,可以适用于不同类型的关系型数据库运行,利用事务日志和定时任务及时清理缓存和解锁,减少占用资源,不存在引起数据库资源使用过高的风险。
[0038]
尽管已经示出和描述了本发明的实施例,对于本领域的普通技术人员而言,可以理解在不脱离本发明的原理和精神的情况下可以对这些实施例进行多种变化、修改、替换和变型,本发明的范围由所附权利要求及其等同物限定。
当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1