深入理解PostgreSQL 事務(wù)處理
簡介
PostgreSQL 事務(wù)處理(Transaction Processing)是指在數(shù)據(jù)庫中執(zhí)行一系列 SQL 語句,使其成為一個不可分割的操作單元,即 要么全部執(zhí)行成功,要么全部回滾,以確保數(shù)據(jù)的一致性和完整性
準(zhǔn)備工作
- 創(chuàng)建演示表
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 );
基本操作
- 提交事務(wù)
BEGIN; -- 開啟事務(wù)
-- SQL 語句
INSERT INTO users (user_account, hashed_password) VALUES ('Alice', 'xxxx');
COMMIT; -- 提交事務(wù)
- 回滾事務(wù)
BEGIN DELETE FROM users; ROLLBACK;
- 設(shè)置回滾點(diǎn)
SAVEPOINT 允許在事務(wù)內(nèi)部創(chuàng)建回滾點(diǎn),部分 SQL 語句可以回滾,而不影響其他 SQL
BEGIN;
INSERT INTO users (user_account, hashed_password) VALUES ('Alice', 'xxxx');
SAVEPOINT sp1; -- 創(chuàng)建回滾點(diǎn)
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; -- 提交事務(wù)
事務(wù)隔離級別
簡介
在數(shù)據(jù)庫中,事務(wù)隔離級別(Transaction Isolation Levels)用于控制多個事務(wù)并發(fā)執(zhí)行時的可見性,避免數(shù)據(jù)不一致的問題。PostgreSQL 遵循 ACID(原子性、一致性、隔離性、持久性) 原則,并提供四種事務(wù)隔離級別
| 隔離級別 | 臟讀 | 不可重復(fù)讀 | 幻讀 |
|---|---|---|---|
| 讀未提交 | ? 可能發(fā)生 | ? 可能發(fā)生 | ? 可能發(fā)生 |
| 讀已提交(默認(rèn)) | ? 不會發(fā)生 | ? 可能發(fā)生 | ? 可能發(fā)生 |
| 可重復(fù)讀 | ? 不會發(fā)生 | ? 不會發(fā)生 | ? 可能發(fā)生 |
| 可串行化 | ? 不會發(fā)生 | ? 不會發(fā)生 | ? 不會發(fā)生 |
下面我們來逐一介紹
讀未提交/讀已提交
PostgreSQL 不真正支持 讀未提交 這個級別,而是當(dāng)作 **讀已提交 **處理
即,就算你設(shè)置了這個級別,PG 數(shù)據(jù)庫還是會使用 讀已提交 級別事務(wù)隔離
臟讀示例(PG 不支持)
BEGIN; -- 事務(wù)1 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; UPDATE users SET hashed_password = 'new_hash' WHERE user_account = 'Alice'; SELECT txid_current(); -- 查看當(dāng)前事務(wù)id -- 保持事務(wù)未提交 BEGIN; -- 事務(wù)2 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; SELECT * FROM users WHERE user_account = 'Alice'; SELECT txid_current(); ROLLBACK; -- 釋放鎖,事務(wù) 2 的查詢繼續(xù)執(zhí)行
注意:我的 navacat17 版本,一個查詢頁面執(zhí)行的語句是同一個事務(wù),所以想讓上面語句生效,你可能需要開啟兩個查詢頁面,分別執(zhí)行事務(wù) 1 和 2
不可重復(fù)讀
- 事務(wù) 1
BEGIN; SELECT hashed_password FROM users;
- 事務(wù) 2
BEGIN; UPDATE users SET hashed_password = 'xxxx'; COMMIT;
- 事務(wù) 1
SELECT hashed_password FROM users;
問題:事務(wù) 1 在第一次 SELECT 時看到的是 hashed_password 與 第二次查詢時hashed_password 不一致,這就是不可重復(fù)讀
幻讀
- 事務(wù) 1
BEGIN; SELECT COUNT(*) FROM users; -- 假設(shè)是3
- 事務(wù) 2
BEGIN;
INSERT INTO users (user_account, hashed_password) VALUES ('Alice4', 'xxxx');
COMMIT; -- 增加到4
- 事務(wù) 1
SELECT COUNT(*) FROM users; -- 增加到4
問題:事務(wù) 1 在開始時認(rèn)為 users 里數(shù)據(jù)為 3,但在事務(wù)進(jìn)行中,別的事務(wù)插入了一條數(shù)據(jù),事務(wù) 1 重新查詢時,發(fā)現(xiàn)數(shù)據(jù)數(shù)量變了,這就是幻讀!
其余隔離級別,有需求可自行查詢~
設(shè)置事務(wù)隔離級別
在事務(wù)中設(shè)置
BEGIN; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- SQL 語句 COMMIT;
在會話級別設(shè)置
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE;
- 這會影響當(dāng)前會話中的所有事務(wù)
在 PostgreSQL 配置文件 postgresql.conf 設(shè)置(全局)
default_transaction_isolation = 'read committed'
- 影響所有數(shù)據(jù)庫的默認(rèn)隔離級別
自動提交
PostgreSQL 默認(rèn)開啟自動提交模式,即每條 SQL 語句都會被自動提交。如果要手動管理事務(wù),需要顯式使用 BEGIN
SET AUTOCOMMIT TO OFF;
到此這篇關(guān)于深入理解PostgreSQL 事務(wù)處理的文章就介紹到這了,更多相關(guān)PostgreSQL 事務(wù)處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- PostgreSQL如何查看事務(wù)所占有的鎖實(shí)操指南
- PostgreSQL 存儲過程的進(jìn)階講解(含游標(biāo)、錯誤處理、自定義函數(shù)、事務(wù))
- PostgreSQL長事務(wù)與失效的索引查詢淺析介紹
- PostgreSQL長事務(wù)概念解析
- PostgreSQL數(shù)據(jù)庫事務(wù)插入刪除及更新操作示例
- PostgreSQL事務(wù)回卷實(shí)戰(zhàn)案例詳析
- 基于Postgresql 事務(wù)的提交與回滾解析
- PostgreSQL數(shù)據(jù)庫事務(wù)實(shí)現(xiàn)方法分析
- PostgreSQL數(shù)據(jù)庫事務(wù)出現(xiàn)未知狀態(tài)的處理方法
相關(guān)文章
使用PostgreSQL為表或視圖創(chuàng)建備注的操作
這篇文章主要介紹了使用PostgreSQL為表或視圖創(chuàng)建備注的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01
在PostgreSQL中設(shè)置表中某列值自增或循環(huán)方式
這篇文章主要介紹了在PostgreSQL中設(shè)置表中某列值自增或循環(huán)方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01
PostgreSQL 臨時表空間的實(shí)現(xiàn)
PostgreSQL使用臨時表空間來存儲查詢執(zhí)行過程中產(chǎn)生的臨時數(shù)據(jù),本文主要介紹了PostgreSQL臨時表空間的實(shí)現(xiàn),具有一定的參考價值,感興趣的可以了解一下2025-06-06
基于PostgreSQL的時序數(shù)據(jù)庫TimescaleDB的基本用法和概念
時序數(shù)據(jù)是指按照時間順序存儲的數(shù)據(jù),TimescaleDB是一個開源的、擴(kuò)展了PostgreSQL的時序數(shù)據(jù)庫擴(kuò)展,本文就給大家詳細(xì)的介紹一下基于PostgreSQL的時序數(shù)據(jù)庫TimescaleDB的基本用法和概念,需要的朋友可以參考下2023-06-06
CentOS 7下安裝PostgreSQL 9.6的教程分享
PostgreSQL在我心目中的地位要遠(yuǎn)遠(yuǎn)高于MySQL,雖然流行對比MySQL低很對,但是功能性一致走在MySQL的前面。下面這篇文章主要介紹了CentOS 7下安裝PostgreSQL數(shù)據(jù)庫的方法,需要的朋友可以參考借鑒,一起來看看吧。2017-02-02
PostgreSQL初始化配置的實(shí)現(xiàn)小結(jié)
本文主要介紹了PostgreSQL初始化配置的實(shí)現(xiàn)小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-11-11
PostgreSQL 分區(qū)表的 ALTER TABLE 語句執(zhí)行機(jī)制解析
這篇文章主要介紹了PostgreSQL 分區(qū)表的 ALTER TABLE 語句執(zhí)行機(jī)制解析的相關(guān)資料,需要的朋友可以參考下2026-02-02
PostgreSQL已經(jīng)存在的表怎么設(shè)置id自增長詳解
這篇文章主要介紹了如何為已有的PostgreSQL表設(shè)置ID字段為自增,包括創(chuàng)建序列、設(shè)置默認(rèn)值、可能的表結(jié)構(gòu)修改以及重置序列的步驟,需要的朋友可以參考下2025-03-03

