悲观锁详解

news2024/11/29 7:33:09

如果将悲观锁(Pessimistic Lock)对应到现实生活中来。悲观锁有点像是一位悲观的人,总是会假设最坏的情况,避免出现问题。

什么是悲观锁?

悲观锁是一种在并发控制中使用的策略,它假设最坏的情况,即默认认为数据在处理过程中极有可能被其他事务修改。因此,当一个事务开始读取数据时,悲观锁会立即对数据加锁,阻止其他事务对该数据进行任何修改,直到当前事务完成(提交或回滚)后才释放锁。这种机制可以有效避免数据冲突,但可能会导致较低的并发性能,因为其他事务可能需要等待锁的释放才能继续执行。 

 Java 中synchronizedReentrantLock等独占锁就是悲观锁思想的实现。 

悲观锁适用于写操作较多的场景,或者数据竞争非常激烈的环境。在数据库管理系统中,实现悲观锁通常通过以下几种方式:

  1. 行级锁:只锁定被访问的数据行。
  2. 表级锁:锁定整个表,所有试图访问该表的其他事务都必须等待。
  3. 共享锁/排他锁:共享锁允许多个事务同时读取同一资源,但不允许写入;而排他锁则既不允许其他事务读也不允许写,保证了数据的一致性。

行级锁 (Row-Level Lock)

  • 定义:行级锁是指锁定数据库中的单个数据行。当一个事务执行更新或删除操作时,它会锁定受影响的数据行,以防止其他事务同时修改这些行。
  • 优点
    • 提高并发性能,因为只有特定的行被锁定,其他未受锁影响的行仍然可以被其他事务访问。
    • 减少锁竞争,提高系统的整体吞吐量。
  • 缺点
    • 锁管理开销较大,尤其是当大量行被锁定时。
    • 可能会导致死锁问题,需要有效的死锁检测和解决机制。

行级锁通常通过SELECT ... FOR UPDATE或类似语法来实现。这会锁定查询返回的行,直到事务结束。 

START TRANSACTION;  -- 开始一个新事务
SELECT * FROM orders WHERE order_id = 12345 FOR UPDATE;  -- 锁定订单ID为12345的记录
-- 在这里执行更新操作
UPDATE orders SET status = 'processed' WHERE order_id = 12345;
COMMIT;  -- 提交事务,释放锁

表级锁 (Table-Level Lock)

  • 定义:表级锁是锁定整个表。一旦一个事务对某个表加了锁,其他事务就不能对该表进行任何读写操作(取决于锁的类型),直到该锁被释放。
  • 优点
    • 实现简单,管理开销小。
    • 适用于小表或者写操作频繁且数据一致性要求非常高的场景。
  • 缺点
    • 降低了并发性能,因为所有试图访问该表的事务都必须等待锁的释放。
    • 对于大型表来说,可能会导致严重的性能瓶颈。

可以使用LOCK TABLES命令或者通过SELECT ... FOR UPDATE加上适当的提示来锁定整个表。 

START TRANSACTION;
LOCK TABLES orders WRITE;  -- 写锁,阻止其他会话对orders表进行读写
-- 进行更新操作
UPDATE orders SET status = 'processed' WHERE order_id = 12345;
UNLOCK TABLES;  -- 解锁表
COMMIT;

共享锁 (Shared Lock, S-Lock)

  • 定义:共享锁允许多个事务同时读取同一资源,但不允许其他事务获取排他锁来修改数据。这意味着多个事务可以同时持有共享锁,但不能有事务同时持有共享锁和排他锁。
  • 应用场景:主要用于读取操作,确保在读取期间数据不会被修改。
  • 特点
    • 读取之间互不干扰。
    • 读取与写入相互排斥。

共享锁允许并发读取但阻止写入。 

BEGIN;
SELECT * FROM orders WHERE order_id = 12345 FOR UPDATE NOWAIT;  -- 立即获取共享锁
-- 可以有多个这样的选择同时发生
COMMIT;

排他锁 (Exclusive Lock, X-Lock)

  • 定义:排他锁阻止其他事务对锁定的资源进行任何形式的访问,无论是读还是写。这意味着如果一个事务对某资源加了排他锁,则其他事务既不能读也不能写这个资源,直到当前事务释放锁。
  • 应用场景:主要用于写操作,确保数据的一致性和完整性。
  • 特点
    • 写操作之间互斥。
    • 写操作与读操作互斥。

排他锁阻止其他所有事务对该资源进行读取或写入。 

START TRANSACTION;
SELECT * FROM orders WHERE order_id = 12345 FOR UPDATE;  -- 获取排他锁
-- 执行更新
UPDATE orders SET status = 'processed' WHERE order_id = 12345;
COMMIT;

注意事项

  • 死锁:在使用锁时要注意避免死锁(线程获得锁的顺序不当时)的发生。可以通过设置合理的超时时间、使用更细粒度的锁(如行级锁)来减少死锁的风险。
  • 性能影响:长时间持有锁会影响系统的并发处理能力。尽量减少事务的持续时间和锁持有的时间。高并发的场景下,激烈的锁竞争会造成线程阻塞,大量阻塞线程会导致系统的上下文切换,增加系统的性能开销。
  • 事务管理:确保每个事务尽可能短,并且只包含必要的操作,以减少锁的竞争和等待时间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2249598.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

最新Linux下使用conda配置Java23或17保姆教程(附赠安装包)

随着技术的不断进步,越来越多的开发者开始在Linux环境下进行Java应用的开发。Java 17作为长期支持版本(LTS),提供了许多新特性和性能改进。当然现在最新的是Java23,这个还作为实验版本未广泛使用。对于需要管理多个编程…

RHEL7+Oracle11.2 RAC集群-多路径(multipath+udev)安装步骤

RHEL7Oracle11.2RAC集群-多路径(multipathudev)安装 配置虚拟存储 使用StarWind Management Console软件,配置存储 dggrid1: 1g*3 Dggrid2: 1g*3 Dgsystem: 5g*1 系统表空间,临时表空间,UNDO,参数文件…

PyTorch 模型转换为 ONNX 格式

PyTorch 模型转换为 ONNX 格式 在深度学习领域,模型的可移植性和可解释性是非常重要的。本文将介绍如何使用 PyTorch 训练一个简单的卷积神经网络(CNN)来分类 MNIST 数据集,并将训练好的模型转换为 ONNX 格式。我们还将讨论 PTH …

VM Virutal Box的Ubuntu虚拟机与windows宿主机之间设置共享文件夹(自动挂载,永久有效)

本文参考如下链接 How to access a shared folder in VirtualBox? - Ask Ubuntu (1)安装增强功能(Guest Additions) 首先,在网上下载VBoxGuestAdditions光盘映像文件 下载地址:Index of http://…

CA系统(file.h---申请认证的处理)

#pragma once #ifndef FILEMANAGER_H #define FILEMANAGER_H #include <string> namespace F_ile {// 读取文件&#xff0c;返回文件内容bool readFilename(const std::string& filePath);bool readFilePubilcpath(const std::string& filePath);bool getNameFro…

【Git】Git 命令参考手册

目录 Git 命令参考手册1. 创建仓库1.1 创建一个新的本地仓库1.2 克隆一个仓库1.3 克隆仓库到指定目录 2. 提交更改2.1 显示工作目录中已修改的文件&#xff0c;准备提交2.2 将文件添加到暂存区&#xff0c;准备提交2.3 将所有已修改的文件添加到暂存区&#xff0c;准备提交2.4 …

【Linux系列】Chrony时间同步服务器搭建完整指南

1. 简介 Chrony是一个用于Linux系统的高效、精准的时间同步工具&#xff0c;通常用于替代传统的NTP&#xff08;Network Time Protocol&#xff09;服务。Chrony不仅在系统启动时提供快速的时间同步&#xff0c;还能在时钟漂移较大的情况下进行及时调整&#xff0c;因此广泛应…

数据库日志

MySQL中有哪些日志 1&#xff0c;redo log重做日志 redo log是物理机日志&#xff0c;因为它记录的是对数据页的物理修改&#xff0c;而不是SQL语句。 作用是确保事务的持久性&#xff0c;redo log日志记录事务执行后的状态&#xff0c;用来恢复未写入 data file的已提交事务…

【vue for beginner】Vue该怎么学?

&#x1f308;Don’t worry , just coding! 内耗与overthinking只会削弱你的精力&#xff0c;虚度你的光阴&#xff0c;每天迈出一小步&#xff0c;回头时发现已经走了很远。 vue2 和 vue3 Vue2现在正向vue3逐渐更新中&#xff0c;官方vue2已经不再更新。 这个历程和当时的pyt…

【Ubuntu 24.04】How to Install and Use NVM

参考 下载 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash激活 Activate NVM: Once the installation script completes, you need to either close and reopen the terminal or run the following command to use nvm immediately. exp…

SeggisV1.0 遥感影像分割软件【源代码】讲解

在此基础上进行二次开发&#xff0c;开发自己的软件&#xff0c;例如&#xff1a;【1】无人机及个人私有影像识别【2】离线使用【3】变化监测模型集成【4】个人私有分割模型集成等等&#xff0c;不管是您用来个人学习 还是公司研发需求&#xff0c;都相当合适&#xff0c;包您满…

Python轴承故障诊断 (21)基于VMD-CNN-BiTCN的创新诊断模型

往期精彩内容&#xff1a; Python-凯斯西储大学&#xff08;CWRU&#xff09;轴承数据解读与分类处理 Pytorch-LSTM轴承故障一维信号分类(一)-CSDN博客 Pytorch-CNN轴承故障一维信号分类(二)-CSDN博客 Pytorch-Transformer轴承故障一维信号分类(三)-CSDN博客 三十多个开源…

使用docker搭建hysteria2服务端

源链接&#xff1a;https://github.com/apernet/hysteria/discussions/1248 官网地址&#xff1a;https://v2.hysteria.network/zh/docs/getting-started/Installation/ 首选需要安装docker和docker compose 切换到合适的目录 cd /home创建文件夹 mkdir hysteria创建docke…

基于Java实现的潜艇大战游戏

基于Java实现的潜艇大战游戏 一.需求分析 1.1 设计任务 本次游戏课程设计小组成员团队合作的方式&#xff0c;通过游戏总体分析设计&#xff0c;场景画面的绘制&#xff0c;游戏事件的处理&#xff0c;游戏核心算法的分析实现&#xff0c;游戏的碰撞检测&#xff0c;游戏的反…

课题组自主发展了哪些CMAQ模式预报相关的改进技术?

空气污染问题日益受到各级政府以及社会公众的高度重视&#xff0c;从实时的数据监测公布到空气质量数值预报及预报产品的发布&#xff0c;我国在空气质量监测和预报方面取得了一定进展。随着计算机技术的高速发展、空气污染监测手段的提高和人们对大气物理化学过程认识的深入&a…

深入解析下oracle date底层存储方式

之前我们介绍了varchar2和char的数据库底层存储格式&#xff0c;今天我们介绍下date类型的数据存储格式&#xff0c;并通过测试程序快速获取一个日期。 一、环境搭建 1.1&#xff0c;创建表 我们还是创建一个测试表t_code&#xff0c;并插入数据&#xff1a; 1.2&#xff0c;…

【论文复现】SRGAN

1. 项目结构 如何生成文件夹的文件目录呢? 按住shift键,右击你要生成目录的文件夹,选择“在此处打开Powershell窗口” 在命令窗口里输入命令“tree”,按回车。就会显示出目录结构。 ├─.idea │ └─inspectionProfiles ├─benchmark_results ├─data │ ├─test …

Kubernetes 之 Ingress 和 Service 的异同点

1. 概念与作用 1.1 Ingress Ingress 是什么&#xff1f; Ingress主要负责七层负载&#xff0c;将外部 HTTP/HTTPS 请求路由到集群内部的服务。它可以基于域名和路径定义规则&#xff0c;从而将外部请求分配到不同的服务。 ingress作用 提供 基于 HTTP/HTTPS 的路由。 支持 …

结构体详解+代码展示

系列文章目录 &#x1f388; &#x1f388; 我的CSDN主页:OTWOL的主页&#xff0c;欢迎&#xff01;&#xff01;&#xff01;&#x1f44b;&#x1f3fc;&#x1f44b;&#x1f3fc; &#x1f389;&#x1f389;我的C语言初阶合集&#xff1a;C语言初阶合集&#xff0c;希望能…

Springboot项目搭建(7)

1.概要 2.Layout主页布局 文件地址&#xff1a;src\views\Layout.vue 2.1 script行为模块 从elementUI中选取图标图案。 <script setup> import {Management,Promotion,UserFilled,User,Crop,EditPen,SwitchButton,CaretBottom } from "element-plus/icons-vue…