面试官:MySQL如何实现分布式读写锁?

本文详细介绍了如何在MySQL中实现分布式读写锁,包括获取和释放锁的步骤,以及处理死锁的方法。通过两表配合和定时job,确保了锁的正确管理和死锁预防。同时,文中提供了R锁的获取与释放过程。
摘要由CSDN通过智能技术生成

3.2、int count = (update t_read_write_lock set w_count=1 where r_count = 0)

3.3、如果count==1,则插入一条上锁日志,锁类型是0,状态是0:insert t_lock_log (resource_id,lock_type,status,create_time) values (#{resource_id},0,0,‘当前时间’);

3.4、提交事务;

}

4、如果3.2的count==1,继续向下执行,否则终止业务

5、执行业务操作,业务操作过程如下

{

5.1、业务库开启事务

5.2、执行业务

5.3、更新锁日志记录的状态为1,条件中必须带上status=0:int updateLogCount = (update t_lock_log set status=1 where id=#{日志记录id} and status = 0)

5.4、if(updateLogCount==1){

5.5、提交事务

}else{

5.6、回滚事务【走到这里说明更新锁日志记录失败了,说明t_lock_log的status被其他地方改掉了,被防止死锁的job修改了】

}

}

6、释放锁,过程如下

{

6.1、开启事务

6.2、释放锁:update t_read_write_lock set w_count=0 where w_count = 1 and resource_id = #{resource_id}

6.3、更新锁日志状态为2:update t_lock_log set status=2 where id = #{日志记录id}

6.4、提交事务

}

2.3、死锁的处理

上面这个是正常流程,如果第 3 步执行完了,也就是上锁 W 锁成功,但是执行到第 6 步之前,系统挂了,此时 W 锁没有释放,会出现死锁。

此时我们需要一个 job,通过这个 job 来释放长时间还未释放的锁,比如过了 10 分钟,锁还未被释放的,job 的逻辑如下

1、获取10分钟之前锁未释放的锁日志列表:select * from t_lock_log where status in (0,1) and create_time+10分钟<=当前时

间的;

2、轮询获取的日志列表,释放锁,操作如下

{

2.1、开启事务

2.2、if(t_lock_log.lock_type==0){

//lock_type为0表示是W锁,下面准备释放W锁

//先将日志状态更新为2,注意条件中带上version作为条件,这里使用到了乐观锁,可以确保并发修改时只有一个count的值为1

int count = (update t_lock_log set status=2 where id = #{日志记录id} and version = #{日志记录.version})

if(count==1){

//将w_count置为0

update t_read_write_lock set w_count=0 where w_count = 1 and resource_id = #{resource_id}

}

}else{

//准备释放R锁

//先将日志状态置为2

int count = (update t_lock_log set status=2 where id = #{日志记录id} and version = #{日志记录.version})

if(count==1){

//将r_count置为r_count-1,注意条件中带上r_count - 1>=0

update t_read_write_lock set r_count=r_count-1 where r_count - 1>=0 and resource_id 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值