死磕 java同步系列之mysql分布式锁

本文探讨了在高并发场景下,随着服务演进,单机锁不再适用的问题,介绍了MySQL分布式锁的概念、实现原理和使用方法。通过示例展示了如何使用`GET_LOCK()`和`RELEASE_LOCK()`函数创建分布式锁,并在Java中实现。文章强调了加锁和释放锁必须在同一会话、可重入性的特点,以及分布式环境下的注意事项。最后,讨论了MySQL分布式锁的优缺点,如减轻数据库压力、自动释放锁和改造成本低,但也指出其可能增加数据库负载、占用连接数等问题。
摘要由CSDN通过智能技术生成

问题

(1)什么是分布式锁?

(2)为什么需要分布式锁?

(3)mysql如何实现分布式锁?

(4)mysql分布式锁的优点和缺点?

简介

随着并发量的不断增加,单机的服务迟早要向多节点或者微服务进化,这时候原来单机模式下使用的synchronized或者ReentrantLock将不再适用,我们迫切地需要一种分布式环境下保证线程安全的解决方案,今天我们一起来学习一下mysql分布式锁如何实现分布式线程安全。

基础知识

mysql中提供了两个函数——get_lock('key', timeout)release_lock('key')——来实现分布式锁,可以根据key来加锁,这是一个字符串,可以设置超时时间(单位:秒),当调用release_lock('key')或者客户端断线的时候释放锁。

它们的使用方法如下:

mysql> select get_lock('user_1', 10);
    -> 1
mysql> select release_lock('user_1');
    -> 1

get_lock('user_1', 10)如果10秒之内获取到锁则返回1,否则返回0;

release_lock('user_1')如果该锁是当前客户端持有的则返回1,如果该锁被其它客户端持有着则返回0,如果该锁没有被任何客户端持有则返回null;

多客户端案例

为了便于举例【本篇文章由“彤哥读源码”原创,请支持原创,谢谢!】,这里的超时时间全部设置为0,也就是立即返回。

时刻 客户端A 客户端B
1 get_lock(‘user_1’, 0) -> 1 -
2 - get_lock(‘user_1’, 0) -> 0
3 - release_lock(‘user_1’, 0) -> 0
4 release_lock(‘user_1’, 0) -> 1 -
5 release_lock(‘user_2’, 0) -> null -
6 - get_lock(‘user_1’, 0) -> 1
7 - release_lock(‘user_1’, 0) -> 1

Java实现

为了方便快速实现,这里使用 springboot2.1 mybatis 实现,并且省略spring的配置,只列举主要的几个类。

定义Locker接口

接口中只有一个方法,入参1为加锁的key,入参2为执行的命令。

public interface Locker {
   
    void lock(String key, Runnable command);
}

mysql分布式锁实现

mysql的实现中要注意以下两点:

(1)加锁、释放锁必须在同一个session(同一个客户端)中,所以这里不能使用Mapper接口的方式调用,因为Mapper接口有可能会导致不在同一个session。

(2)可重入性是通过ThreadLocal保证的;

@Slf4j
@Component
public class MysqlLocker implements Locker {
   

    private static final ThreadLocal<SqlSessionWrapper> localSession = new ThreadLocal<>();

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    @Override
    public void lock(String key, Runnable command) {
   
        // 加锁、释放锁必须使用同一个session
        SqlSessionWrapper sqlSessionWrapper = localSession.get();
        if (sqlSessionWrapper == null) {
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值