当前位置: 首页 > news >正文

Django事务

1. 事务基础概念

1.1 什么是事务?

事务是具有以下特性(ACID)的数据库操作单元:

  • 原子性 (Atomicity):事务是一个不可分割的工作单位,事务中的操作要么全部发生,要么全部不发生。

  • 一致性 (Consistency):事务必须使数据库从一个一致性状态变换到另一个一致性状态。例如,转账前后两个账户的总金额应保持不变。

  • 隔离性 (Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务。数据库提供了不同的隔离级别(如读未提交、读已提交、可重复读、串行化)来平衡一致性和性能。

  • 持久性 (Durability):一旦事务提交,它对数据库中数据的改变就是永久性的。

1.2 Django 中的事务支持

Django 默认使用自动提交模式,每个查询都会立即提交到数据库。但你可以手动控制事务。

2. 事务管理方式

2.1 使用装饰器管理事务
2.1.1 函数视图

from django.db import transaction
from django.http import JsonResponse
from .models import Account@transaction.atomic # 使用装饰器确保此视图中的数据库操作在一个事务中执行
def test_view(request, from_id, to_id, amount):try:amount = float(amount)# 获取账户对象,select_for_update 用于在事务中锁定行,防止并发修改from_account = Account.objects.select_for_update().get(pk=from_id)to_account = Account.objects.select_for_update().get(pk=to_id)# 检查转出账户余额是否充足if from_account.balance < amount:return JsonResponse({"status": "error", "message": "余额不足"})# 执行转账操作from_account.balance -= amountto_account.balance += amount# 保存到数据库from_account.save()to_account.save()return JsonResponse({"status":"success"})except Exception as e:# 如果发生任何异常,Django 会自动回滚事务return JsonResponse({"status": "error"})

2.1.2 类视图

class TestView(View):@method_decorator(transaction.atomic)def post(self, request):try:return JsonResponse({'success': True})except Exception as e:return JsonResponse({'success': False})

2.2 使用上下文管理器管理事务

def transfer_funds(sender_id, receiver_id, amount):try:# 使用上下文管理器明确事务边界with transaction.atomic():...except ValueError as e:# 处理业务逻辑错误print(f"Transfer failed: {e}")except Exception as e:# 处理其他异常,事务会自动回滚print(f"Unexpected error: {e}")

3、保存点(Savepoints)

对于复杂的事务,可以使用保存点来实现部分回滚:


from django.db import transactiondef complex_operation():with transaction.atomic(): # 开启外部事务obj1 = ModelA.objects.create(field='value') # 操作1sid = transaction.savepoint() # 设置保存点try:obj2 = ModelB.objects.create(field=obj1.pk) # 操作2except Exception:transaction.savepoint_rollback(sid) # 回滚到保存点,操作2被撤销,操作1仍有效raise # 继续抛出异常,让外部事务决定是否回滚transaction.savepoint_commit(sid) # 提交保存点
# 外部事务结束,所有操作(包括操作1和2)最终提交

4、其他

4.1 隔离级别

Django 本身不直接提供隔离级别的配置,但可以通过数据库后端或原始SQL来设置。

4.1.1 数据库后端配置

DATABASES = {'default': {'ENGINE': 'django.db.backends.postgresql','NAME': 'mydatabase','USER': 'mydatabaseuser','PASSWORD': 'mypassword','HOST': '127.0.0.1','PORT': '5432','OPTIONS': {# PostgreSQL 隔离级别设置, 'read uncommitted', 'read committed'(默认), 'repeatable read', 'serializable''isolation_level': 'read committed',# MySQL 隔离级别设置,'READ UNCOMMITTED', 'READ COMMITTED', 'REPEATABLE READ'(默认), 'SERIALIZABLE'# 'isolation_level': 'READ-COMMITTED',},}
}

4.2 在代码中设置隔离级别
# 使用原始SQLfrom django.db import connection, transactiondef set_isolation_level():with transaction.atomic():# 设置事务隔离级别with connection.cursor() as cursor:# PostgreSQLcursor.execute("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE")# MySQL# cursor.execute("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE")# SQLite (默认就是SERIALIZABLE)# cursor.execute("PRAGMA read_uncommitted = 0")# 执行事务操作# ...# 使用上下文管理器from contextlib import contextmanager
from django.db import connection@contextmanager
def serializable_transaction():with transaction.atomic():with connection.cursor() as cursor:cursor.execute("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE")yield

4.2 transaction.non_atomic_requests

在 Django 的设置文件 (settings.py) 中,你可以通过配置 ATOMIC_REQUESTS = True为指定的数据库开启​​全局事务模式。这意味着:

  • 每个 HTTP 请求都会被自动包裹在一个数据库事务中。

  • 如果视图函数成功返回响应,Django 会自动提交事务。

  • 如果视图函数抛出异常,Django 会自动回滚事务。

而 @transaction.non_atomic_requests装饰器的作用就是​​让被装饰的视图函数不受上述全局事务规则的限制​​,恢复为 Django 默认的自动提交模式

4.2.1 基本用法

from django.db import transaction@transaction.non_atomic_requests
def my_view(request):# 这个视图函数中的数据库操作将在自动提交模式下运行,# 不会受到全局事务设置的影响。do_stuff()

4.2.2 指定数据库

from django.db import transaction@transaction.non_atomic_requests(using='other')
def my_other_view(request):# 此视图仅对别名为 'other' 的数据库禁用全局事务。do_stuff_on_the_other_database()

5、总结

在Django中使用事务,关键在于识别出哪些数据库操作需要作为一个不可分割的单元。通过 @transaction.atomic装饰器或 with transaction.atomic()上下文管理器,你可以清晰地界定事务的范围。

文章转载自:xclic

原文链接:Django事务 - xclic - 博客园

体验地址:JNPF快速开发平台

http://www.dtcms.com/a/366774.html

相关文章:

  • 《Docker 零基础入门到实战:容器化部署如此简单,运维效率直接拉满》
  • 【有鹿机器人自述】我在社区的365天:扫地、卖萌、治愈人心
  • Android集成OpenCV4实例
  • Java 与 Docker 的最佳实践
  • docker更新jar包,懒人执行脚本
  • MaxKB4j智能体平台 Docker Compose 快速部署教程
  • 飞算JavaAI全面解析:重塑Java开发流程的智能引擎
  • 【数学建模】用Matlab玩转图论:从画图到求最短路径
  • 想要给文档加密?2025年顶尖文件加密软件分享
  • C++并发编程-23. 线程间切分任务的方法
  • uniapp vue页面传参到webview.nvue页面的html或者另一vue中
  • Web应用:返回图片URL
  • Python快速入门专业版(一):Windows/macOS/Linux 系统环境搭建(附常见报错解决)
  • 【连接器专题】案例:带屏蔽膜FPC出现概率性短路,真是供应商的锅?
  • EasyVoice与cpolar:构建私域有声平台的本地化方案
  • Spring线程池ThreadPoolTaskExecutor‌详解
  • 隔空盗刷、AI钓鱼、代理劫持…金融黑产竟进化至此?
  • Elasticsearch 8 中 Nested 数据类型的使用方法
  • 【iOS】 懒加载
  • 一文吃透 CSS 伪类:从「鼠标悬停」到「斑马纹表格」的 30 个实战场景
  • 中值滤波、方框滤波、高斯滤波、均值滤波、膨胀、腐蚀、开运算、闭运算
  • HTML图片标签及路径详解
  • Python开篇撬动未来的万能钥匙 从入门到架构的全链路指南
  • 工厂模式总结
  • C++知识
  • C 盘清理技巧分享:释放磁盘空间,提升系统性能
  • 将 PDF 转换为 TIFF 图片:简单有效的 Java 教程
  • 数据传输,数据解析与写数据库
  • django全国小米su7的行情查询系统(代码+数据库+LW)
  • 阿瓦隆 A15 Pro 221TH/S:SHA-256 算力与高效能耗