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

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

相关推荐
盒马盒马2 分钟前
Redis:zset类型
数据库·redis
程序员是干活的3 分钟前
私家车开车回家过节会发生什么事情
java·开发语言·软件构建·1024程序员节
煸橙干儿~~13 分钟前
分析JS Crash(进程崩溃)
java·前端·javascript
2401_8543910814 分钟前
Spring Boot大学生就业招聘系统的开发与部署
java·spring boot·后端
Amor风信子15 分钟前
华为OD机试真题---跳房子II
java·数据结构·算法
静听山水16 分钟前
mysql语句执行过程
数据库·mysql
虽千万人 吾往矣35 分钟前
golang gorm
开发语言·数据库·后端·tcp/ip·golang
杨荧41 分钟前
【JAVA开源】基于Vue和SpringBoot的洗衣店订单管理系统
java·开发语言·vue.js·spring boot·spring cloud·开源
mariokkm1 小时前
Django一分钟:在Django中怎么存储树形结构的数据,DRF校验递归嵌套模型的替代方案
数据库·django·sqlite
陈逸轩*^_^*1 小时前
Java 网络编程基础
java·网络·计算机网络