面试题 --- 乐观锁与悲观锁

乐观锁(Optimistic Locking)

乐观锁是基于一种假设:即多个事务同时访问同一数据的概率较低,因此它们不会经常产生冲突。在这种机制下乐观锁(Optimistic Locking)

乐观锁是基于一种假设:即多个事务同时访问同一数据的概率较低,因此它们不会经常产生冲突。在这种机制下,事务在开始时不会立即锁定数据,而是在提交事务时检查数据是否被其他事务修改过。如果数据未被修改,则事务成功提交;如果数据已被修改,则事务会回滚。

在数据库中实现乐观锁通常有以下几种方法:

时间戳(Timestamp):在数据表中添加一个额外的列,通常称为"时间戳"或"版本号"。每次数据被修改时,这个时间戳或版本号都会更新。查询数据时,会检查当前时间戳是否与数据库中的时间戳一致。如果一致,则允许更新;如果不一致,表示数据在读取和更新之间已被修改,事务会失败。

版本号(Version Number):类似于时间戳,但使用整数作为版本号。每次数据更新时,版本号递增。事务在更新数据时会检查版本号,只有当版本号与预期相匹配时,才进行更新并将版本号递增。

悲观锁(Pessimistic Locking)

悲观锁则是基于另一种假设:即多个事务同时访问同一数据的概率较高,可能会导致冲突。因此,悲观锁在事务开始时就会锁定所需的数据,防止其他事务进行修改,直到当前事务提交或回滚。

悲观锁的实现方式通常包括:

行锁(Row Locks):数据库在行级别上加锁,确保事务在读取或写入特定数据时不会被其他事务干扰。

表锁(Table Locks):数据库在整个表级别上加锁,这通常会影响性能,因为它阻止了对表的所有访问,直到锁被释放。

选择乐观锁还是悲观锁

选择使用乐观锁还是悲观锁取决于具体的应用场景和并发水平。乐观锁适合冲突较少的环境,可以提高并发性能,因为它避免了锁定带来的开销。而悲观锁更适用于冲突频繁的环境,尤其是在数据修改非常关键且不能容忍失败的情况下。

在数据库中实现乐观锁通常有以下几种方法:

时间戳(Timestamp):在数据表中添加一个额外的列,通常称为"时间戳"或"版本号"。每次数据被修改时,这个时间戳或版本号都会更新。查询数据时,会检查当前时间戳是否与数据库中的时间戳一致。如果一致,则允许更新;如果不一致,表示数据在读取和更新之间已被修改,事务会失败。

版本号(Version Number):类似于时间戳,但使用整数作为版本号。每次数据更新时,版本号递增。事务在更新数据时会检查版本号,只有当版本号与预期相匹配时,才进行更新并将版本号递增。

悲观锁(Pessimistic Locking)

悲观锁则是基于另一种假设:即多个事务同时访问同一数据的概率较高,可能会导致冲突。因此,悲观锁在事务开始时就会锁定所需的数据,防止其他事务进行修改,直到当前事务提交或回滚。

悲观锁的实现方式通常包括:

行锁(Row Locks):数据库在行级别上加锁,确保事务在读取或写入特定数据时不会被其他事务干扰。

表锁(Table Locks):数据库在整个表级别上加锁,这通常会影响性能,因为它阻止了对表的所有访问,直到锁被释放。

选择乐观锁还是悲观锁

选择使用乐观锁还是悲观锁取决于具体的应用场景和并发水平。乐观锁适合冲突较少的环境,可以提高并发性能,因为它避免了锁定带来的开销。而悲观锁更适用于冲突频繁的环境,尤其是在数据修改非常关键且不能容忍失败的情况下。

使用场景:

乐观锁:在商品库存表中,商品销售频繁,在更新库存信息时采用乐观锁。我们采用的方法是:给库存表的数据表添加一个标识字段------版本号(version),在每次执行入库的sql语句时,在执行条件中添加一个where条件判断version是否与之前读取的一致,如果满足,则修改对应内容以及版本号更新(如+1),如果不满足,则事务回滚,重新执行。
悲观锁:在一个银行转账系统中,转账操作涉及从一个账户扣除金额并添加到另一个账户。这种操作对数据的一致性要求非常高,因为同时进行的转账操作可能会导致错误的余额计算。在这种情况下,可以使用悲观锁。当一个转账操作开始时,系统会锁定涉及的账户记录,确保在此期间其他转账操作无法修改这些记录。直到转账操作完成并释放锁后,其他事务才能继续进行。

相关推荐
ZWZhangYu1 小时前
LangChain 构建向量数据库和检索器
数据库·langchain·easyui
pianmian12 小时前
类(JavaBean类)和对象
java
我叫小白菜2 小时前
【Java_EE】单例模式、阻塞队列、线程池、定时器
java·开发语言
feifeigo1232 小时前
升级到MySQL 8.4,MySQL启动报错:io_setup() failed with EAGAIN
数据库·mysql·adb
Albert Edison3 小时前
【最新版】IntelliJ IDEA 2025 创建 SpringBoot 项目
java·spring boot·intellij-idea
超级小忍3 小时前
JVM 中的垃圾回收算法及垃圾回收器详解
java·jvm
weixin_446122463 小时前
JAVA内存区域划分
java·开发语言·redis
火龙谷4 小时前
【nosql】有哪些非关系型数据库?
数据库·nosql
勤奋的小王同学~4 小时前
(javaEE初阶)计算机是如何组成的:CPU基本工作流程 CPU介绍 CPU执行指令的流程 寄存器 程序 进程 进程控制块 线程 线程的执行
java·java-ee
TT哇4 小时前
JavaEE==网站开发
java·redis·java-ee