PostgreSQL Serializable隔离级别工作原理及测试异常疑问
为什么Serializable隔离级别下你的并行事务没触发报错?
问题根源:对Serializable隔离级别的误解
你以为Serializable会强制事务严格串行执行,只要并发就会报错,但实际上PostgreSQL的Serializable隔离级别是乐观并发控制——它允许事务并发执行,只在提交阶段检查是否存在串行化异常(即无法找到一个串行执行顺序来等价于当前并发执行的结果),只有存在异常时才会回滚其中一个事务。
你的示例中,两个事务的操作不会产生串行化异常:
- transaction1是只读事务,它读取的是事务启动时的快照数据;
- transaction2是写事务,它更新目标行并提交。
这两个事务的并发执行,可以对应两种合法的串行执行顺序:
- 先执行transaction1(读旧值),再执行transaction2(更新值);
- 先执行transaction2(更新值),再执行transaction1(读新值)。
两种串行顺序的结果都是合理的,PostgreSQL不会检测到冲突,因此不会触发报错。
触发Serializable冲突的正确示例
要触发串行化报错,需要构造存在写偏斜或基于快照读的更新冲突的场景。比如两个事务都基于同一个初始值进行更新:
transaction1.py
import psycopg2 import time conn = psycopg2.connect("dbname=your_db user=your_user password=your_pwd") cursor = conn.cursor() cursor.execute("START TRANSACTION ISOLATION LEVEL SERIALIZABLE;") # 读取初始余额 cursor.execute("SELECT balance FROM customers WHERE name = '1'") balance = cursor.fetchall()[0][0] # 模拟业务处理延迟 time.sleep(10) # 基于读取的值更新 cursor.execute("UPDATE customers SET balance = %s WHERE name = '1'", (balance + 50,)) cursor.execute("COMMIT") cursor.close() conn.close()
transaction2.py
import psycopg2 import time conn = psycopg2.connect("dbname=your_db user=your_user password=your_pwd") cursor = conn.cursor() cursor.execute("START TRANSACTION ISOLATION LEVEL SERIALIZABLE;") # 读取同一个初始余额 cursor.execute("SELECT balance FROM customers WHERE name = '1'") balance = cursor.fetchall()[0][0] # 模拟业务处理延迟 time.sleep(10) # 基于读取的值更新 cursor.execute("UPDATE customers SET balance = %s WHERE name = '1'", (balance + 100,)) cursor.execute("COMMIT") cursor.close() conn.close()
先运行transaction1,再运行transaction2,当第二个事务提交时,PostgreSQL会检测到串行化冲突,抛出类似如下的错误:
psycopg2.errors.SerializationFailure: could not serialize access due to read/write dependencies among transactions DETAIL: Reason code: Canceled on identification as a pivot, during commit attempt. HINT: The transaction might succeed if retried.
补充说明
PostgreSQL的Serializable隔离级别依赖快照隔离+串行化冲突检测:
- 读操作使用快照,不会阻塞写操作;
- 写操作会获取行级锁,但不会阻塞快照读;
- 只有当并发事务的执行逻辑无法对应任何串行执行顺序时,才会在提交时触发回滚。
内容的提问来源于stack exchange,提问作者blablatron
相关产品推荐
相关产品推荐

