集群多JVM分布式锁实现

本文介绍了三种分布式锁的实现方式:基于数据库乐观锁(已废弃)、Redis和Zookeeper。数据库锁依赖数据库,易出现单点、无失效时间等问题;Redis锁性能好但一致性不强;Zookeeper则提供高可用性和强一致性,但需要客户端实现锁操作。每种方案都有其优缺点,适用于不同的场景。
摘要由CSDN通过智能技术生成
基于数据库表乐观锁 (基本废弃)

要实现分布式锁,最简单的⽅方式可能就是直接创建⼀一张锁表,然后通过操作该表中的数据来实现了了。
当我们要锁住某个⽅法或资源时,我们就在该表中增加一条记录,想要释放锁的时候就删除这条记录。
比如创建这样一张数据库表:

CREATE TABLE `methodLock` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`method_name` varchar(64) NOT NULL DEFAULT '' COMMENT '锁定的⽅方法名', `desc` varchar(1024) NOT NULL DEFAULT '备注信息',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '保存数据时间,⾃自动⽣生成',
PRIMARY KEY (`id`),
UNIQUE KEY `uidx_method_name` (`method_name `) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='锁定中的⽅方法';

当我们想要锁住某个方法时,执行以下SQL:

insert into methodLock(method_name,desc) values (‘method_name’,‘desc’)

因为我们对method_name做了唯一性约束,这里如果有多个请求同时提交到数据库的话,数据库会保证只有一个操作可以成功,那么我们就可以认为操作成功的那个线程获得了该方法的锁,可以执方法体内容。
当⽅法执行完毕之后,想要释放锁的话,需要执⾏行行以下sql:

delete from methodLock where method_name ='method_name'

上面说到这种方式基本废弃,那么这种简单的实现会存在哪些问题呢?

  1. 这把锁会强依赖数据库的可用性,数据库是一个单点,⼀旦数据库挂掉,会导致业务系统不可⽤。
  2. 这把锁并没有失效时间,⼀旦解锁操作失败,就会导致锁记录一直存在数据库中,其它线程无法再获得到锁。
  3. 这把锁只能是非阻塞的,因为数据的insert操作,⼀旦插⼊入失败就会直接报错。没有获得锁的线程并不会进入排队列,要想再次获得锁就要再次触发获得锁操作。
  4. 这把锁是非重⼊的,同⼀个线程在没有释放锁之前无法再次获得该锁。因为数据已经存在了。当然,我们也可以有其它方式解决上面的问题。
  • 针对数据库是单点问题搞两个数据库,数据之前双向同步。⼀旦挂掉快速切换到备库上。
  • 针对没有失效时间?我们可以做一个定时任务,每隔一定时间把数据库中的超时数据清理理一遍。
  • 针对非阻塞的?搞⼀个自旋while循环,直到insert成功再返回成功。
  • 针对⾮重入的?我们可以在数据库表中加个字段,记录当前获得锁的机器的主机信息和线程信息,那么下次再获取锁的时候先查询数据库,如果当前机器的主机信息和线程信息在数据库可以查到的话,直接把锁分配给他就可以了。
  • 基于数据库排他锁 除了可以通过增删操作数据表中的记录以外,其实还可以借助数据中自带的锁来实现分布式的锁。我们⽤刚刚创建的那张数据库表。可以通过数据库的排他锁来实现分布式锁。 基于MySql的InnoDB 引擎,可以使用以下方法来实现加锁操作。
    伪代码如下:
public boolean lock(){
    connection.setAutoCommit(false)
    while(true){
        try{
            result = select * from methodLock where method_name=xxx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值