【PostgreSQL】【第4章】PostgreSQL的事务

1. 事务基础与ACID特性

1.1 事务基本概念
  • 事务:一组相关操作的集合,要么全部成功,要么全部失败。
  • 核心目的 :保证数据操作的原子性 和一致性。
1.2 ACID特性详解
特性 描述
原子性 (Atomicity) 事务是最小执行单位,操作要么全成功,要么全失败(如转账操作:扣款和到账必须同时成功或失败)。
一致性 (Consistency) 事务完成后数据必须保持一致性状态(如A账户-100,B账户必须+100)。
隔离性 (Isolation) 事务间相互隔离,避免中间状态被其他事务感知(如事务A未提交时,事务B无法看到中间结果)。
持久性 (Durability) 事务提交后数据永久存储到磁盘(即使系统崩溃也不丢失)。
sql 复制代码
-- 示例:银行转账事务
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;

2. 事务操作与保存点

2.1 基本事务操作
  1. 开启事务 :BEGIN
  2. 提交事务 :COMMIT
  3. 回滚事务 :ROLLBACK
sql 复制代码
BEGIN;
INSERT INTO test (id, name) VALUES (7, 'Test');
-- 若操作有误,可回滚
ROLLBACK;
-- 或提交
COMMIT;
2.2 保存点(Savepoint)
  • 作用:将大事务分段,允许部分回滚。

  • 关键命令 :

    sql 复制代码
    SAVEPOINT savepoint_name;
    ROLLBACK TO savepoint_name;

示例:

sql 复制代码
BEGIN;
INSERT INTO orders (product_id, quantity) VALUES (101, 2);
SAVEPOINT after_order;
UPDATE inventory SET stock = stock - 2 WHERE product_id = 101;
-- 若库存更新失败,回滚到保存点
ROLLBACK TO after_order;
COMMIT;

3. 事务隔离级别与并发问题

3.1 并发问题类型
问题 描述
脏读 (Dirty Read) 读取到其他事务未提交的数据(必须避免)。
不可重复读 (Non-Repeatable Read) 同一事务多次查询同一数据结果不一致(如中间有其他事务提交了修改)。
幻读 (Phantom Read) 同一事务多次查询数据集不一致(如其他事务插入新数据)。
3.2 PostgreSQL隔离级别
隔离级别 解决的问题 特点
读已提交 (Read Committed) 脏读 PostgreSQL默认级别,事务只能看到已提交的数据。
可重复读 (Repeatable Read) 脏读、不可重复读 通过快照保证事务内数据一致性(实际效果等同于串行化)。
串行化 (Serializable) 所有问题 最高隔离级别,事务串行执行(性能较低)。

4. MVCC多版本并发控制

4.1 MVCC核心机制
  • 实现原理 :每行数据维护多个版本(通过xmin和xmax字段记录事务版本号)。
  • 读写分离 :
    • 读操作访问旧版本数据(避免阻塞写操作)。
    • 写操作生成新版本(不影响正在进行的读操作)。

示例:

sql 复制代码
-- 事务A
BEGIN;
SELECT * FROM products WHERE id = 1; -- 读取版本100

-- 事务B
BEGIN;
UPDATE products SET price = 200 WHERE id = 1;
COMMIT; -- 生成版本101

-- 事务A再次查询仍读取版本100
COMMIT;

5. 锁机制

5.1 表锁与行锁对比
锁类型 语法示例 行为
表锁 LOCK TABLE test IN ACCESS EXCLUSIVE MODE; 锁定整张表(阻塞所有读写操作)。
行锁 SELECT * FROM test WHERE id = 1 FOR UPDATE; 锁定单行(其他事务无法修改该行,但可读取)。
5.2 行锁使用场景
sql 复制代码
-- 事务A获取行锁
BEGIN;
SELECT * FROM orders WHERE id = 100 FOR UPDATE;

-- 事务B尝试修改被阻塞
BEGIN;
UPDATE orders SET status = 'shipped' WHERE id = 100; -- 等待事务A提交

6. 实践建议

  1. 避免大事务:使用保存点或最终一致性方案(如消息队列)。
  2. 优先行锁:减少锁竞争,提升并发性能。
  3. 合理选择隔离级别:根据业务需求平衡一致性和性能。
  4. 监控锁冲突 :使用pg_locks视图排查阻塞问题。
sql 复制代码
-- 查看当前锁状态
SELECT * FROM pg_locks;
相关推荐
AC赳赳老秦16 分钟前
OpenClaw 数据引用规范自动生成:为公开数据构建可信来源标注与标准引用体系
大数据·开发语言·汇编·数据库·人工智能·deepseek·openclaw
小蒜学长1 小时前
校园社团招新网站的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端·校园社团招新网站
布莱克6052 小时前
MySQL 增删改查(CRUD)语法详解
数据库·mysql·增删改查
Dovis(誓平步青云)2 小时前
几个方案来回选不定?做一个随时切换的候选推荐页
android·java·服务器·开发语言·javascript·数据库·智能化
2501_933670793 小时前
2027届大数据管理与应用求职数字化转型顾问:项目、SQL、业务理解怎么排优先级
数据库·sql
东方护航数据恢复(深圳)4 小时前
物流案例:勒索病毒 Mallox 加密 ERP 数据库,旧备份 + 残留页重组实录【东方护航数据恢复深圳店】
数据库·数据恢复·勒索病毒·二次开盘·开盘·数据镜像
.Hypocritical.4 小时前
Redis从入门到实战:核心原理、场景落地与避坑指南
数据库·redis·缓存
梦想画家4 小时前
SQLMesh Python 模型入门(二):依赖管理、引擎实战与内存优化
数据库·python·sqlmesh
Omics Pro4 小时前
经典多组学整合算法→商用云平台
数据库·人工智能·算法·机器学习·自然语言处理
xcLeigh4 小时前
【KingbaseES数据库教程】国产化信创背景下的数据库选型与初识
linux·数据库·windows·kes·数据选型