bigywater.tech
Django · 48

ATOMIC_REQUESTS 的工作方式

ATOMIC_REQUESTS = True 就是「每个请求一个事务」。它的边界比想象中窄:什么会回滚、什么不会?这篇分别在关闭与开启下打同一组 URL,看表里留下什么。

只有异常回滚
视图返回 500 响应不算失败,事务照样提交;只有抛出异常才回滚
中间件在外
中间件里的写入不在视图事务里,回滚不影响它们
流式响应
生成器里的写入发生在事务结束之后

两组结果

实测 · 本机执行输出
GET /raise/      → status 500;表里留下: ['middleware-after-view', 'middleware-before-view', 'view-write']
GET /500/        → status 500;表里留下: ['middleware-after-view', 'middleware-before-view', 'view-write']
GET /ok/         → status 200;表里留下: ['middleware-after-view', 'middleware-before-view', 'view-write']
GET /nonatomic/  → status 500;表里留下: ['middleware-after-view', 'middleware-before-view', 'view-write']
视图里 in_atomic_block → in_atomic_block=False
on_commit 回调是否已经执行(请求返回之后): ['on_commit 回调', '视图即将返回响应']
遍历流式响应时抛出: ValueError
流式响应:表里留下: ['generator-write', 'middleware-after-view', 'middleware-before-view', 'view-write']
实测 · 本机执行输出
GET /raise/      → status 500;表里留下: ['middleware-after-view', 'middleware-before-view']
GET /500/        → status 500;表里留下: ['middleware-after-view', 'middleware-before-view', 'view-write']
GET /ok/         → status 200;表里留下: ['middleware-after-view', 'middleware-before-view', 'view-write']
GET /nonatomic/  → status 500;表里留下: ['middleware-after-view', 'middleware-before-view', 'view-write']
视图里 in_atomic_block → in_atomic_block=True
on_commit 回调是否已经执行(请求返回之后): ['视图即将返回响应', 'on_commit 回调']
遍历流式响应时抛出: ValueError
流式响应:表里留下: ['generator-write', 'middleware-after-view', 'middleware-before-view', 'view-write']

同一组视图:抛异常、返回 500、正常返回、被 non_atomic_requests 排除、on_commit、流式响应。

怎么理解边界

分步演示:请求即事务

ATOMIC_REQUESTS
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / Python 3.14.7 / Django 6.1.1(默认用 SQLite,其它数据库会在文中注明),用 django.test.Client 或真实的本机服务器进程实测;计时用 time.perf_counter,数字每次运行会有小幅抖动。SQLite;用 django.test.Client(raise_request_exception=False)
    • 没有验证:PostgreSQL 上的相同行为、多数据库下 ATOMIC_REQUESTS 只对指定别名生效、异步视图(ATOMIC_REQUESTS 对 async 视图不支持——文档说法,本文没有验证)、视图里手动 atomic 与它的嵌套
    京ICP备2026067502号-1京公网安备11010502063487号