bigywater.tech
Django · 47

数据库隔离级别与 Django

Django 没有自己的隔离级别,用的是数据库默认。但默认是什么?换成 REPEATABLE READ 之后,代码要改什么?这篇在 PostgreSQL 上用两个线程构造「事务里别人改了同一行」,看每个级别下读与写的结果。

read committed
PostgreSQL 的默认隔离级别(SHOW transaction_isolation)
100 → 200
READ COMMITTED:同一事务两次读同一行,读到别人提交的修改
serialize
REPEATABLE READ:并发更新同一行 → could not serialize access,应用要捕获并重试

默认:READ COMMITTED

实测 · 本机执行输出
  read committed

没有设置任何选项时的行为。

更严格的级别

在 DATABASES['default']['OPTIONS'] 里设置 isolation_level(psycopg 3 的 IsolationLevel)。上一节的对照见演示。更严格的级别把「读到旧值」变成了「写的时候失败」——好处是不会悄悄基于旧值提交,代价是必须写重试逻辑。

分步演示:三个级别

隔离级别
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / Python 3.14.7 / Django 6.1.1(默认用 SQLite,其它数据库会在文中注明),用 django.test.Client 或真实的本机服务器进程实测;计时用 time.perf_counter,数字每次运行会有小幅抖动。PostgreSQL 16.15(本机临时实例,端口 9423);每个级别各用一个全新的 Django 进程;别人的修改由另一个线程的独立连接完成
    • 没有验证:MySQL(默认 REPEATABLE READ,语义不同)、幻读与写偏斜的复现、SERIALIZABLE 下的 SerializationFailure 重试模式、间隙锁
    京ICP备2026067502号-1京公网安备11010502063487号