乐观锁和悲观锁的理解及如何实现,有哪些实现方式?

乐观锁和悲观锁是数据库并发控制中的两种不同策略。

乐观锁(Optimistic Locking)的核心理念是“相信用户”。乐观锁假设大多数用户会按照正确的顺序使用数据,因此它不会阻止并发访问,而是在数据提交时检查是否有冲突。乐观锁适用于读多写少的场景,因为冲突检测的成本相对较低。

悲观锁(Pessimistic Locking)则与之相反,它总是假设最坏的情况,即数据会被并发访问并修改,因此悲观锁通过阻止并发访问来实现数据的互斥访问,以提高数据的完整性。悲观锁适用于写多读少或者完全不读的情况。

在实现方式上,乐观锁和悲观锁都有不同的方法来实现。

乐观锁

  1. 版本控制(Versioning):每个数据项都有一个版本号,每次更新时都会检查版本号是否一致。不一致时说明有其他用户在并发访问时进行了修改,此时会抛出异常。
  2. 乐观锁冲突检测(Optimistic Conflict Detection):通过SQL语句中的WHERE子句,在更新前检查是否存在冲突的数据行。例如,可以使用UPDATE语句检查是否已经有其他用户在更新相同的行。
  3. 乐观锁的时间戳:数据项中存储一个时间戳字段,表示最后一次更新的时间。当读取数据时,如果发现数据项的时间戳和当前时间差较大,说明可能有其他用户在之后进行了更新。

悲观锁

  1. 数据库级别的锁(Database-level Locks):通过数据库系统提供的锁机制(如MySQL的行级锁、表级锁等)来控制并发访问。当一个事务需要修改数据时,会先获取锁,直到事务结束时释放锁。
  2. 应用程序级别的锁(Application-level Locks):通过应用程序代码实现锁机制,如使用synchronized关键字或Lock接口。这种方式通常用于实现复杂的业务逻辑或跨多个线程/进程的操作。

总的来说,乐观锁和悲观锁各有优缺点。乐观锁适用于读多写少的场景,但需要手动处理冲突检测,可能需要在数据提交时进行额外的检查。悲观锁适用于写多读少或者完全不读的情况,通过数据库系统的锁机制来实现数据的互斥访问,可以提高数据的完整性。具体使用哪种策略取决于你的应用场景和需求。

悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,都是在做操作之前先上锁。再比如 Java 里面的同步原语 synchronized关键字的实现也是悲观锁。

mysql悲观锁的方法:1、首先利用【select ... for update】加锁,操作完成后使用commit来释放锁;

乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,常见的乐观锁实现方式有两种,分别是:
1、版本号机制;其中,通过版本号机制实现乐观锁是最经典的方法。版本号机制一般是在数据表中加上一个数据库版本号version字段,使用版本标识来确定读到的数据与提交时的数据是否一致。提交后修改版本标识,不一致时可以采取丢弃和再次尝试的策略
2、CAS算法,当多个线程尝试使用 CAS 同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试
bfbcd548e059636bc98f2bb9e439810c_1656.png

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值