深入理解PostgreSQL 事务处理

 更新时间:2025年06月16日 09:37:26   作者:熊大如如  
PostgreSQL事务处理确保数据一致性,支持四种隔离级别,处理脏读、不可重复读和幻读问题,并可通过会话或配置文件设置,自动提交默认开启,感兴趣的可以了解一下

简介

PostgreSQL 事务处理(Transaction Processing)是指在数据库中执行一系列 SQL 语句,使其成为一个不可分割的操作单元,即 要么全部执行成功,要么全部回滚,以确保数据的一致性和完整性

准备工作

  • 创建演示表
CREATE TABLE "public"."users" (
  "user_account" varchar(32) COLLATE "pg_catalog"."default" NOT NULL,
  "username" varchar(32) COLLATE "pg_catalog"."default",
  "user_avatar" varchar(64) COLLATE "pg_catalog"."default",
  "user_profile" varchar(512) COLLATE "pg_catalog"."default",
  "hashed_password" varchar COLLATE "pg_catalog"."default" NOT NULL
);

基本操作

  • 提交事务
BEGIN; -- 开启事务

-- SQL 语句
INSERT INTO users (user_account, hashed_password) VALUES ('Alice', 'xxxx');

COMMIT; -- 提交事务
  • 回滚事务
BEGIN

DELETE FROM users;

ROLLBACK;
  • 设置回滚点

SAVEPOINT 允许在事务内部创建回滚点,部分 SQL 语句可以回滚,而不影响其他 SQL

BEGIN;

INSERT INTO users (user_account, hashed_password) VALUES ('Alice', 'xxxx');
SAVEPOINT sp1; -- 创建回滚点

INSERT INTO users (user_account, hashed_password) VALUES ('Alice2', 'xxxx');
SAVEPOINT sp2;

INSERT INTO users (user_account, hashed_password) VALUES ('Alice3', 'xxxx');
ROLLBACK TO sp2;

COMMIT; -- 提交事务

事务隔离级别

简介

在数据库中,事务隔离级别(Transaction Isolation Levels)用于控制多个事务并发执行时的可见性,避免数据不一致的问题。PostgreSQL 遵循 ACID(原子性、一致性、隔离性、持久性) 原则,并提供四种事务隔离级别

隔离级别脏读不可重复读幻读
读未提交✅ 可能发生✅ 可能发生✅ 可能发生
读已提交(默认)❌ 不会发生✅ 可能发生✅ 可能发生
可重复读❌ 不会发生❌ 不会发生✅ 可能发生
可串行化❌ 不会发生❌ 不会发生❌ 不会发生

下面我们来逐一介绍

读未提交/读已提交

PostgreSQL 不真正支持 读未提交 这个级别,而是当作 **读已提交 **处理

即,就算你设置了这个级别,PG 数据库还是会使用 读已提交 级别事务隔离

脏读示例(PG 不支持)

BEGIN; -- 事务1
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
UPDATE users SET hashed_password = 'new_hash' WHERE user_account = 'Alice';
SELECT txid_current(); -- 查看当前事务id
-- 保持事务未提交

BEGIN; -- 事务2
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM users WHERE user_account = 'Alice';
SELECT txid_current();


ROLLBACK; -- 释放锁,事务 2 的查询继续执行

注意:我的 navacat17 版本,一个查询页面执行的语句是同一个事务,所以想让上面语句生效,你可能需要开启两个查询页面,分别执行事务 1 和 2

不可重复读

  • 事务 1
BEGIN;
SELECT hashed_password FROM users;
  • 事务 2
BEGIN;
UPDATE users SET hashed_password = 'xxxx';
COMMIT;
  • 事务 1
SELECT hashed_password FROM users;

问题:事务 1 在第一次 SELECT 时看到的是 hashed_password 与 第二次查询时hashed_password 不一致,这就是不可重复读

幻读

  • 事务 1
BEGIN;
SELECT COUNT(*) FROM users; -- 假设是3
  • 事务 2
BEGIN;
INSERT INTO users (user_account, hashed_password) VALUES ('Alice4', 'xxxx');
COMMIT; -- 增加到4
  • 事务 1
SELECT COUNT(*) FROM users; -- 增加到4

问题:事务 1 在开始时认为 users 里数据为 3,但在事务进行中,别的事务插入了一条数据,事务 1 重新查询时,发现数据数量变了,这就是幻读

其余隔离级别,有需求可自行查询~

设置事务隔离级别

在事务中设置

BEGIN;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- SQL 语句
COMMIT;

在会话级别设置

SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE;
  • 这会影响当前会话中的所有事务

在 PostgreSQL 配置文件 postgresql.conf 设置(全局)

default_transaction_isolation = 'read committed'
  • 影响所有数据库的默认隔离级别

自动提交

PostgreSQL 默认开启自动提交模式,即每条 SQL 语句都会被自动提交。如果要手动管理事务,需要显式使用 BEGIN

SET AUTOCOMMIT TO OFF;

到此这篇关于深入理解PostgreSQL 事务处理的文章就介绍到这了,更多相关PostgreSQL 事务处理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • 使用PostgreSQL为表或视图创建备注的操作

    使用PostgreSQL为表或视图创建备注的操作

    这篇文章主要介绍了使用PostgreSQL为表或视图创建备注的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • 在PostgreSQL中设置表中某列值自增或循环方式

    在PostgreSQL中设置表中某列值自增或循环方式

    这篇文章主要介绍了在PostgreSQL中设置表中某列值自增或循环方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • PostgreSQL 临时表空间的实现

    PostgreSQL 临时表空间的实现

    PostgreSQL使用临时表空间来存储查询执行过程中产生的临时数据,本文主要介绍了PostgreSQL临时表空间的实现,具有一定的参考价值,感兴趣的可以了解一下
    2025-06-06
  • postgresql 启动与停止操作

    postgresql 启动与停止操作

    这篇文章主要介绍了postgresql 启动与停止操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • 基于PostgreSQL的时序数据库TimescaleDB的基本用法和概念

    基于PostgreSQL的时序数据库TimescaleDB的基本用法和概念

    时序数据是指按照时间顺序存储的数据,TimescaleDB是一个开源的、扩展了PostgreSQL的时序数据库扩展,本文就给大家详细的介绍一下基于PostgreSQL的时序数据库TimescaleDB的基本用法和概念,需要的朋友可以参考下
    2023-06-06
  • CentOS 7下安装PostgreSQL 9.6的教程分享

    CentOS 7下安装PostgreSQL 9.6的教程分享

    PostgreSQL在我心目中的地位要远远高于MySQL,虽然流行对比MySQL低很对,但是功能性一致走在MySQL的前面。下面这篇文章主要介绍了CentOS 7下安装PostgreSQL数据库的方法,需要的朋友可以参考借鉴,一起来看看吧。
    2017-02-02
  • PostgreSQL初始化配置的实现小结

    PostgreSQL初始化配置的实现小结

    本文主要介绍了PostgreSQL初始化配置的实现小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-11-11
  • PostgreSQL设置时间自动更新的示例代码

    PostgreSQL设置时间自动更新的示例代码

    在我们日常开发中,在设计数据库字段的时候不可避免的都要created_time以及updated_time两个时间戳字段,作用大家也都一目了然,下面将为大家详细介绍PostgreSQL设置时间自动更新的方法,需要的朋友可以参考下
    2025-03-03
  • PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析

    PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析

    这篇文章主要介绍了PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析的相关资料,需要的朋友可以参考下
    2026-02-02
  • PostgreSQL已经存在的表怎么设置id自增长详解

    PostgreSQL已经存在的表怎么设置id自增长详解

    这篇文章主要介绍了如何为已有的PostgreSQL表设置ID字段为自增,包括创建序列、设置默认值、可能的表结构修改以及重置序列的步骤,需要的朋友可以参考下
    2025-03-03

最新评论