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

乐观锁(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),如果不满足,则事务回滚,重新执行。
悲观锁:在一个银行转账系统中,转账操作涉及从一个账户扣除金额并添加到另一个账户。这种操作对数据的一致性要求非常高,因为同时进行的转账操作可能会导致错误的余额计算。在这种情况下,可以使用悲观锁。当一个转账操作开始时,系统会锁定涉及的账户记录,确保在此期间其他转账操作无法修改这些记录。直到转账操作完成并释放锁后,其他事务才能继续进行。

相关推荐
明夜之约18 小时前
Spring Boot 自动装配源码
java·spring boot·后端
Leaton Lee18 小时前
Spring Boot分层架构详解:从Controller到Service再到Mapper的完整流程
java·spring boot·后端·架构
Micro麦可乐18 小时前
Spring Boot 实战:从零设计一个短链系统(含完整代码与数据库设计)
数据库·spring boot·后端·哈希算法·雪花算法·短链系统
Jinkxs18 小时前
Resilience4j- 与 Spring Boot 快速集成:自动配置与基础注解使用
java·spring boot·后端
辣机小司18 小时前
【踩坑记录:Spring Boot 配置文件读取值不一致?警惕 YAML 的“八进制陷阱”与 SnakeYAML 版本之谜】
java·spring boot·后端·yaml·踩坑记录
码农阿豪18 小时前
从零到一:Spring Boot快速接入金仓数据库实战
数据库·spring boot·后端
鼎讯信通18 小时前
风电光缆运维提质增效:G-4000A 光缆故障追踪仪破解风场巡检难题
运维·网络·数据库
三十..19 小时前
MySQL 从入门到高可用架构实战精要
运维·数据库·mysql
fangdengfu12319 小时前
ES分析系统各个服务日志占用量
java·前端·elasticsearch
云烟成雨TD19 小时前
Spring AI 1.x 系列【51】可观测性技术选型
java·人工智能·spring