分布式锁-数据库实现

 

1:for update 的原理

select 检索出的数据, for update 加上了一把锁,其他的人是不能修改这个数据的,也不能在给这个数据加锁。其他线程可以检索出来,但是我在用 for update 再给这些数据加锁是加不上的,因为这个锁呢,已经被前一个线程给锁住了。其他人是不能给它加锁的,在加锁的期间,其他人也不能修改这些数据。因为update 更新数据呢,是要获取这些数据的锁的

2:代码实现

    @Transactional(rollbackFor = Exception.class)
    @RequestMapping("/database")
    public String databaseLock () throws InterruptedException {
        log.info("进入方法");
        BusinessLock businessLock = businessLockMapper.getLock("demo");
        if (ObjectUtils.isEmpty(businessLock)) {
            log.info("分布式锁找不到");
        }
        log.info("进入锁");
        Thread.sleep(6000);
        log.info("方法执行完成");
        return "方法执行完成";
    }

 mapper 里面的sql

        SELECT * FROM business_lock WHERE  business_code = #{businessCode}  FOR UPDATE
  •  开启两个实例,端口分别是  8080  8088
  • 下图 8080  应用   
  1. 58:16秒      进入方法
  2. 58:16秒      进入锁
  3. 58:22秒      方法执行完成

 

  • 下图 8088  应用   
  1. 58:17秒      进入方法
  2. 58:22秒      进入锁
  3. 58:28秒      方法执行完成

在代码中我们让获取到锁的应用休眠6秒 ,8080 和 8088 差不多同一时间进入方法,

但是8080更早一些所有获得到了锁,而8088就在数据库中阻塞,等待获取锁。

在16秒 8080获得锁等待6秒 22秒释放锁,这时  8088才拿到了锁。说明在多个应用中锁是有生效的。

教程源码+sql下载

3:用native 测for update

  • 先将当前页面的数据库自动提交先关掉

为什么要先关掉呢?你现在检索出来以后或者for update 加了锁,加了锁以后它马上事务呢就会自动的去提交,事务提交了。锁就会自动释放了。其他的会话,还会检索出这条数据来

  • 下图:默认是自动提交事务的 

  • 下图:这时候都是没有关闭自动提交事务的。两者都可以执行加锁页面。说明没有起到我们想要的作用
  • 下图:关闭两个窗口的自动提交事务
  •  再次检索带有  for update 关键字的sql 。这时候锁被左窗口锁住了,导致右窗口无法加锁。这时候在  左窗口执行commit 提交事务操作,右窗口立马就查询出数据了 。说明锁是生效的

  • 左窗口执行 for update ,右窗口不使用  for update 而是直接执行查询 是可以查询出数据的 

4:总结

 

  

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis分布式锁是一种常见的并发控制机制,用于在分布式系统中解决多个请求并发访问资源时的互斥问题。当多个客户端同时尝试获取同一锁时,只有一个客户端能够成功获取,其他客户端则需要等待,直到锁被释放。这通常通过在Redis中设置一个过期时间的键来实现,例如使用`SETNX`命令设置一个唯一的锁标识,如果该键不存在则设置并返回true,表示获得锁。 数据库事务则是数据库操作的一种执行方式,它保证了对数据库的一组操作要么全部成功,要么全部回滚,从而保持数据的一致性。在一个事务中,所有相关的操作被视为一个原子操作,这有助于避免并发修改导致的数据不一致问题。 当Redis分布式锁数据库事务同时使用时,通常会在以下几个场景中: 1. **分布式事务管理**:如果系统需要支持跨数据库的操作,可以先尝试获取Redis锁,成功后开始一个数据库事务。只有在事务内完成所有操作并提交时,才释放锁。如果事务失败(如部分操作出错),锁也会被自动释放,防止数据不一致。 2. **限流与熔断**:在高并发场景下,可能需要使用分布式锁实现限流或熔断机制。先获取锁,如果获取成功,再检查是否超过阈值,如果在事务范围内完成这些操作后,释放锁。 3. **临时存储**:在需要临时存储数据,等待其他服务处理完成后进行持久化的情况,可以先在Redis中获取锁,然后在事务中进行数据写入,事务完成后,如果一切正常,释放锁。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值