分布式锁是一种用于协调分布式系统中多个进程或线程之间对共享资源的访问的机制。在分布式系统中,多个进程或线程同时访问共享资源可能会导致数据不一致或并发冲突的问题。分布式锁通过保证在同一时间只有一个进程或线程能够访问共享资源,从而解决了这些问题。
分布式锁在分布式系统中广泛应用于各种场景,例如分布式任务调度、分布式事务、分布式缓存等。它可以保证多个进程或线程之间对共享资源的访问的一致性和正确性,提高系统的可靠性和性能。
无论采用哪种实现方式,分布式锁都需要满足以下几个条件:
在同一时间只能有一个进程或线程持有锁。
同一个进程或线程可以多次获取同一把锁。
当持有锁的进程或线程发生故障时,系统能够自动释放锁。
分布式锁可以通过各种方式实现,常见的实现方式包括:
使用数据库的事务和锁机制来实现分布式锁
创建一张锁表,然后通过操作该表中的数据来实现了。当我们想要获得锁的时候,就可以在该表中增加一条记录,想要释放锁的时候就删除这条记录。
这里为resource 设置为唯一键,防止对同一资源进行多次锁定,保证唯一
CREATE TABLE ojmall_lock (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`resource` int NOT NULL COMMENT '锁定的资源',
`description` varchar(1024) NOT NULL DEFAULT "" COMMENT '描述',
PRIMARY KEY (id),
UNIQUE KEY uiq_idx_resource (resource)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据库分布式锁表';
当我们想要获得锁时,可以插入一条数据
INSERT INTO ojmall_lock(resource, description) VALUES (1, 'lock');
当需要释放锁的时,可以删除这条数据:
DELETE FROM ojmall_lock WHERE resource=1;
乐观锁,顾名思义,就是很乐观,每次更新操作,都觉得不会存在并发冲突,只有更新失败后,才重试。
表中加version字段,每次更新修改,都会自增加一,然后去更新内容时,把查出来的那个版本号,带上条件去更新,如果还是上次那个版本号,就更新,如果不是,表示别人并发修改过了,就继续重试。
一般需要要设置一下重试次数
在分布式系统中,可以通过数据库悲观锁来实现分布式锁。具体实现步骤如下:
需要注意的是,分布式环境下的数据库悲观锁实现存在一些问题,例如数据库单点故障、网络延迟等。为了解决这些问题,可以使用分布式锁中的其他机制,如基于Redis的分布式锁、基于ZooKeeper的分布式锁等。这些机制可以提供更高的可靠性和性能。
使用分布式缓存系统(如Redis)的原子操作来实现分布式锁,
例如通过设置一个特定的缓存键值对来表示锁的状态。
使用ZooKeeper这样的分布式协调服务来实现分布式锁,例如通过创建一个临时节点来表示锁的状态。
参考文章:
https://mp.weixin.qq.com/s?__biz=MzA5NzE1NzY3OA==&mid=2653462355&idx=1&sn=f597248ea9e1f39ace50d26593e3f1a6&chksm=8b792812bc0ea104ad6ad14f6973f9ce4c6fa47c518e28a1638bcd98633a76a25742f3b13395#rd