Django 原子请求(Atomic Requests) 是 Django 中的一个数据库事务处理机制,它确保每个 HTTP 请求作为一个原子性数据库事务执行。
核心概念
1. 原子性保证
- 当启用
ATOMIC_REQUESTS = True时,每个 HTTP 请求被视为一个数据库事务 - 如果请求处理过程中发生异常,该请求内的所有数据库操作都会被回滚
- 如果请求成功完成,所有更改会一次性提交到数据库
2. 配置方式
在 settings.py 中配置:
python
# 为所有数据库连接启用
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'ATOMIC_REQUESTS': True, # 启用原子请求
}
}
# 或为特定数据库连接启用
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'ATOMIC_REQUESTS': False, # 默认不启用
},
'logging_db': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'logs',
'ATOMIC_REQUESTS': True, # 仅为这个连接启用
}
}
工作机制
请求处理流程
开始请求
↓
开始数据库事务
↓
执行视图函数/中间件
↓
请求成功? → 否 → 回滚事务 → 返回错误响应
↓是
提交事务
↓
返回成功响应
使用示例
基本视图
python
from django.http import JsonResponse
from myapp.models import Order, Inventory
def process_order(request):
# 整个视图在单个事务中执行
order = Order.objects.create(user=request.user, amount=100)
# 减少库存
inventory = Inventory.objects.get(product_id=1)
inventory.quantity -= 1
inventory.save()
# 如果这里发生异常,上面两个操作都会被回滚
send_notification(order) # 假设这里可能失败
return JsonResponse({'status': 'success'})
优缺点分析
✅ 优点
- 数据一致性:保证请求内的所有操作要么全部成功,要么全部失败
- 简化开发:不需要手动管理每个视图的事务
- 避免部分更新:防止数据库处于不一致状态
❌ 缺点
- 性能影响:长时间运行的请求会长时间持有数据库连接
- 不适合所有场景 :
- 长时间运行的请求
- 流式响应
- 需要与外部 API 交互的复杂操作
- 可能隐藏错误:自动回滚可能掩盖了需要特殊处理的业务逻辑错误
高级用法
1. 手动控制事务
python
from django.db import transaction
@transaction.non_atomic_requests # 禁用原子请求
def my_view(request):
# 这个视图不在原子事务中运行
pass
@transaction.atomic # 显式开启事务
def another_view(request):
# 显式控制事务
with transaction.atomic():
# 嵌套事务
do_something()
2. 保存点(Savepoints)
python
from django.db import transaction
def complex_operation(request):
sid = transaction.savepoint() # 创建保存点
try:
# 操作1
operation1()
# 操作2
operation2()
except Exception as e:
transaction.savepoint_rollback(sid) # 回滚到保存点
# 执行补偿操作
compensate()
transaction.savepoint_commit(sid) # 提交保存点
最佳实践
推荐使用场景
- 简单的 CRUD 操作
- 银行/金融交易
- 库存管理系统
- 需要强一致性的业务
不推荐使用场景
- 文件上传处理(特别是大文件)
- 长时间运行的后台任务
- 需要与多个外部服务交互的复杂流程
- 实时流式响应
替代方案
python
# 使用更细粒度的事务控制
class OrderView(View):
@transaction.atomic
def post(self, request):
# 只对这个方法使用事务
process_order(request)
def get(self, request):
# 查询操作,不需要事务
return get_orders(request)
配置建议
python
# settings.py 中的推荐配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydb',
'ATOMIC_REQUESTS': False, # 默认关闭,按需开启
}
}
# 然后在需要的事务边界显式使用 @transaction.atomic
注意事项
- 中间件顺序 :
transaction中间件应该在SessionMiddleware之后 - 测试影响:测试时事务行为可能不同
- 数据库支持:不是所有数据库都支持相同级别的事务隔离
- HTTP 方法 :通常只对
POST、PUT、DELETE等修改操作需要事务
总结 :Django 原子请求是一个强大的特性,但应该根据具体业务需求谨慎使用。对于大多数应用,推荐在视图级别使用 @transaction.atomic 装饰器,而不是全局启用 ATOMIC_REQUESTS。