PostgreSQL 事务并发锁
文章目录
- PostgreSQL 事务
- 大家都知道的 ACID
- 事务的基本使用
- 保存点
- PostgreSQL 并发
- 并发问题
- MVCC
- PostgreSQL 锁机制
- 表锁
- 行锁
- 总结
PostgreSQL 事务
大家都知道的 ACID
在日常操作中,对于一组相关操作,通常要求要么都成功,要么都失败。在关系型数据库中,称这一组操作为事务。为了保证整体事务的安全性,有ACID这一说:
- 原子性A:事务是一个最小的执行单位,一次事务中的操作要么都成功,要么都失败。
- 一致性C:在事务完成时,所有数据必须保持在一致的状态。(事务完成后吗,最终结果和预期结果是一致的)
- 隔离性I:一次事务操作,要么是其他事务操作前的状态,要么是其他事务操作后的状态,不存在中间状态。
- 持久性D:事务提交后,数据会落到本地磁盘,修改是永久性的。
PostgreSQL相比于其他数据库,有一个比较大的优化,DDL也可以包含在一个事务中。比如集群中的操作,一个事务可以保证多个节点都构建出一个表,才算成功。
事务的基本使用
PostgreSQL跟MySQL一样,是自动提交事务的。
可以基于关闭PostgreSQL的自动提交事务来进行操作。
但是上述方式比较麻烦,传统的方式。
也可以根据命令处理一个事务:
- begin:开始事务
- commit:提交事务
- rollback:回滚事务
-- 开启事务
begin;
-- 操作
insert into test values (7,'bbb',12,5);
-- 提交事务
commit;
保存点
在PostgreSQL中,保存点(savepoint)用于在事务中创建中间状态,点允许在事务过程中设置临时的“检查点”,以便在必要时回滚事务的一部分。
比如项目中有一个大事务操作超时,回滚成本太高。针对大事务,可以拆分成几个部分,每个部分完成后,构建一个保存点,如果后面操作超时了,回滚到保存点,继续重试。
-- savepoint操作
-- 开启事务
begin;
-- 插入一条数据
insert into test values (8,'铃铛',55,11);
-- 添加一个保存点
savepoint ok1;
-- 再插入数据,比如出了一场
insert into test values (9,'大唐官府',66,22);
-- 回滚到之前的提交点
rollback to savepoint ok1;
-- 就可以开始重试操作,重试成功,commit,失败可以rollback;
commit;
PostgreSQL 并发
并发问题
在不考虑隔离性的前提下,事务的并发可能会出现的问题:
- 脏读:读到了其他事务未提交的数据。(必须避免这种情况)
- 不可重复读:同一事务中,多次查询同一数据,结果不一致,因为其他事务修改造成的。(一些业务中这种不可重复读不是问题)
- 幻读:同一事务中,在修改某个数据后,再次查询还是之前的数据,因为其他事务对数据进行了更新,这种现象为幻读。
针对这些并发问题,关系型数据库有一些事务的隔离级别,一般用4种。
- READ UNCOMMITTED:读未提交
- READ COMMITTED:读已提交,可以解决脏读(PGSQL默认隔离级别)
- REPEATABLE READ:可重复读,可以解决脏读和不可重复读(MySQL默认是这个隔离级别,PGSQL也提供了,但是设置为可重复读,效果还是串行化)
- SERIALIZABLE:串行化
PGSQL在老版本中,只有两个隔离级别,读已提交和串行化,在PGSQL中不存在脏读问题。
MVCC
PostgreSQL中,在事务的并发问题里,也是基于MVCC多版本并发控制去维护数据的一致性。详细内容见多版本并发控制MVCC
首先要清楚,为啥要有MVCC?
如果一个数据库,频繁的进行读写操作,为了保证安全,采用锁的机制。但是如果采用锁机制,如果一些事务在写数据,另外一个事务就无法读数据,会造成读写之间相互阻塞。 所以大多数的数据库都会采用一个机制 多版本并发控制 MVCC 来解决这个问题。
MVCC是一种并发控制的方法,它通过保存数据的多个版本来实现并发访问。在MVCC中,每个事务在开始时获取一个唯一的版本号,然后读取和修改数据时都会带上这个版本号。这样,每个事务只能看到自己的版本号小于或等于自己的数据版本,从而实现了并发访问。
PGSQL中,每张表都会自带两个字段
- xmin:给当前事务分配的数据版本。如果有其他事务做了写操作,并且提交事务了,就给xmin分配新的版本。
- xmax:当前事务没有存在新版本,xmax就是0。如果有其他事务做了写操作,未提交事务,将写操作的版本放到xmax中。提交事务后,xmax会分配到xmin中,然后xmax归0。
基于上图的操作查看效果
事务A
-- 左,事务A
--1、开启事务
begin;
--2、查询某一行数据, xmin = 630,xmax = 0
select xmin,xmax,* from test where id = 8;
--3、每次开启事务后,会分配一个事务ID 事务id=631
select txid_current();
--7、修改id为8的数据,然后在本事务中查询 xmin = 631, xmax = 0
update test set name = '铃铛' where id = 8;
select xmin,xmax,* from test where id = 8;
--9、提交事务
commit;
事务B
-- 右,事务B
--4、开启事务
begin;
--5、查询某一行数据, xmin = 630,xmax = 0
select xmin,xmax,* from test where id = 8;
--6、每次开启事务后,会分配一个事务ID 事务id=632
select txid_current();
--8、事务A修改完,事务B再查询 xmin = 630 xmax = 631
select xmin,xmax,* from test where id = 8;
--10、事务A提交后,事务B再查询 xmin = 631 xmax = 0
select xmin,xmax,* from test where id = 8;
PostgreSQL 锁机制
当然,PostgreSQL也支持表锁和行锁,来控制并发访问。PostgreSQL中主要有两种锁,一个表锁一个行锁。
表锁
表锁就是锁住整张表,也分为很多中模式,其中最核心的两个:
- ACCESS SHARE:共享锁(读锁),读读操作不阻塞,但是不允许出现写操作并行
- ACCESS EXCLUSIVE:互斥锁(写锁),无论什么操作进来,都阻塞。
具体的可以查看官网文档。
PostgreSQL中表锁的实现:
基于LOCK开启表锁,指定表的名字name,其次在MODE中指定锁的模式,NOWAIT可以指定是否在没有拿到锁时,一致等待。
-- 事务1
-- 基于互斥锁,锁住test表
-- 先开启事务
begin;
-- 基于默认的ACCESS EXCLUSIVE锁住test表
lock test in ACCESS SHARE mode;
-- 操作
select * from test;
-- 提交事务,锁释放
commit;
当事务1开启锁住当前表之后,如果使用默认的ACCESS EXCLUSIVE,其他连接操作表时,会直接阻塞住。
如果事务1是基于ACCESS SHARE共享锁时,其他事务是可以查询当前表的。
行锁
PostgreSQL的行锁和MySQL的基本是一模一样的,基于select for update就可以指定行锁。
MySQL中有一个概念,for update时,如果select的查询没有命中索引,可能会锁表。
PostgerSQL有个特点,for update时,如果select的查询没有命中索引,不一定会锁表,依然会实现行锁。
-- 先开启事务
begin;
-- 基于for update 锁住id为3的数据
select * from test where id = 3 for update;
update test set name = 'v1' where id = 3;
-- 提交事务,锁释放
commit;
其他的事务要锁住当前行,会阻塞住。
总结
事务、MVCC和锁是三个相互关联的概念,它们共同保证了数据库的一致性和并发性。
- 事务和MVCC是互相配合的,事务通过MVCC来实现并发控制,保证数据的一致性。
- 锁是事务实现并发控制的一种手段,通过加锁来保证数据的一致性。
相关文章:

PostgreSQL 事务并发锁
文章目录 PostgreSQL 事务大家都知道的 ACID事务的基本使用保存点 PostgreSQL 并发并发问题MVCC PostgreSQL 锁机制表锁行锁 总结 PostgreSQL 事务 大家都知道的 ACID 在日常操作中,对于一组相关操作,通常要求要么都成功,要么都失败。在关系…...

CANoe-Model Editor无法修改ARXML文件的问题、E2E在SOME/IP通信中的使用问题
1、Model Editor无法修改ARXML文件的问题 在CANoe 15软件版本中,Communication Setup导入arxml文件后,可以在model editor中打开arxml并修改配置。关闭model editor后再打开,可以看到修改的配置被保存了。 但是,当我把arxml文件从Communication Setup中移除后,再导入。此…...
Conan安装第三方依赖库时SSL验证失败解决办法
背景 c跨平台项目使用conan进行三方库依赖管理是比较通用的方案,更换开发环境后突然发现conan无法安装三方库了,报错如下: zlib/1.2.12: Not found in local cache, looking in remotes... zlib/1.2.12: Trying with conan-center... ERROR…...

基于springboot+vue的大学生智能消费记账系统
博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…...
Java——》synchronized的使用
推荐链接: 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…...

vue+element使用阿里的图标库保存图标
阿里图标网站iconfont-阿里巴巴矢量图标库 我想使用保存图标,但是element的图标库没有找到可用的,首先在阿里的图标网站搜索保存 发现这个还不错 点击添加入库 点击购物车 点击添加至项目 点击下载到本地 把下载的压缩包里面的文件拖到自己项目里面 在m…...

Day 01 web前端基础知识
首先我们要了解什么事前端? 先简单用文字介绍一下: 一、入门知识 Web前端是指网站或应用程序的用户界面部分。它包括HTML、CSS、JavaScript等语言和技术,用于创建用户可浏览和交互的网页。Web前端的特点在于其交互性和动态性,可…...
Redis 高可用之持久化
目录 Redis 高可用 Redis 持久化 RDB 持久化 触发条件 执行流程 启动时加载 修改配置文件 AOF 持久化 配置 执行流程 命令追加(append) 文件写入(write)和文件同步(sync) 文件重写(rewrite) 文件重写的流程 RDB和AOF的优缺点 Redis 高可用 在web服务器中&…...
生成元 rust解法
如果x加上x的各个数字之和得到y,就说x是y的生成元。给出n(1≤n≤100000),求n的最小生成元。无解输出0。例如,n216,121,2005时的解分别为198,0,1979。 【分析】 本题看起来…...
某ERP系统存在RCE漏洞
文章目录 前言声明一、产品简介二、影响资产三、资产发现四、漏洞测试五、修复方案前言 企望制造纸箱行业ERP系统存在RCE漏洞,攻击者可通过特定Payload注入获取敏感信息。 声明 请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直…...
ElasticSearch 因为索引字段改变,平滑迁移索引
问题: 某个索引创建时,没有按照想要的mapping,进行创建。 有个字段是text,不是想要的keyWord 此时需要重新按照mapping创建新索引,并迁移数据, 一、不使用别名的方式迁移 1. 创建新索引: 使用 Elastics…...
invalid use of incomplete type ‘class Ui::xxx‘
MainWindow 引用自定义窗口报错:invalid use of incomplete type class Ui::xxx mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include "form.h" form.cpp #include "form.h" #include "…...

变压器寿命预测(python代码,Logistic Regression模型预测效果一般,可以做对比实验)
1.数据来源官网:Data for: Root cause analysis improved with machine learning for failure analysis in power transformers - Mendeley Data 点Download All 10kb即可下载数据 2.下载下来后是这样 每一列的介绍: Hydrogen 氢气; Oxyge…...

微信小程序-增加隐私协议弹窗
真的加了非常之久,非常简单的一个功能,但是因为之前没弄过,加上系统有点bug,软件也有点抽风...... 在微信后台配置-更新用户隐私协议信息增加 "__usePrivacyCheck__" : true, 9月15号之后不加也行,好象今天刚刚好9月15…...

分布式事务解决方案之可靠消息最终一致性
分布式事务解决方案之可靠消息最终一致性 什么是可靠消息最终一致性事务 可靠消息最终一致性方案是指当事务发起方执行完成本地事务后并发出一条消息,事务参与方(消息消费者)一定能 够接收消息并处理事务成功,此方案强调的是只要消息发给事务参与方最终…...

ROS学习笔记(四)---使用 VScode 启动launch文件运行多个节点
ROS学习笔记文章目录 01. ROS学习笔记(一)—Linux安装VScode 02. ROS学习笔记(二)—使用 VScode 开发 ROS 的Python程序(简例) 03. ROS学习笔记(三)—好用的终端Terminator 一、什么是launch文件 虽然说Terminator终端是能够比较方便直观的看运行的节点…...
编译Redis时报错: jemalloc/jemalloc.h: No such file or directory
1.编译Redis时出现错误 运行: [rootcentos01 redis-6.2.7]# make & make install报错: zmalloc.h:50:31: fatal error: jemalloc/jemalloc.h: No such file or directory #include <jemalloc/jemalloc.h> 2.解决步骤 2.1 检查gcc是否安装 [r…...
LLM 05-大模型法律
LLM 05-大模型法律 5.1 简介 在这个教程中,我们将探讨法律对大型语言模型的开发和部署有何规定。我们将会按照以下的步骤进行讨论: 新技术与现有法律的关系 与我们之前的讲座一样,比如关于社会偏见的讲座,我们将要讨论的很多内容…...

1-5 AUTOSAR数据交换文件ARXML
总目录——AUTOSAR入门详解AUTOSAR入门详解目录汇总:待续中。。。https://xianfan.blog.csdn.net/article/details/132818463 目录 一、Arxml文件 二、各类ARXML文件 一、Arxml文件 arxml文件是AUTOSAR(Automotive Open System Architecture࿰…...
学习尚硅谷HTML+CSS总结
今天主要学习了颜色像素的四种表达方式,在没学习之前也只会一种RGB颜色的表达方式,虽然其他三种使用的比较少,但有些网页会用其他的表达方式写的我们学过之后就会看得懂,还有文本的设置,字体等等,这些都是后…...

linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7
在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤: 第一步: 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为: // 改为 v…...

篇章二 论坛系统——系统设计
目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...

【Java多线程从青铜到王者】单例设计模式(八)
wait和sleep的区别 我们的wait也是提供了一个还有超时时间的版本,sleep也是可以指定时间的,也就是说时间一到就会解除阻塞,继续执行 wait和sleep都能被提前唤醒(虽然时间还没有到也可以提前唤醒),wait能被notify提前唤醒…...