深入解析:Django事务

news/2025/9/24 13:55:11/文章来源:https://www.cnblogs.com/yfceshi/p/19109118

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 -= amount
to_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 transaction
def complex_operation():
with transaction.atomic(): # 开启外部事务
obj1 = ModelA.objects.create(field='value') # 操作1
sid = transaction.savepoint() # 设置保存点
try:
obj2 = ModelB.objects.create(field=obj1.pk) # 操作2
except 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 在代码中设置隔离级别
# 使用原始SQL
from django.db import connection, transaction
def set_isolation_level():
with transaction.atomic():
# 设置事务隔离级别
with connection.cursor() as cursor:
# PostgreSQL
cursor.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.mzph.cn/news/915779.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

做网站6000左右的电脑网上购物商城系统设计

3.mysql数据库3.10 单表查询3.10.1. 简单查询查询在数据库中使用的频率是最高的&#xff1a;十次查询&#xff0c;一次增删改。1)建表2)插入数据3.10.1.1. 选择字段&#xff1a;selectselect 字段名1,字段名2…… from 表名 where 条件;3.10.1.2. 字段重命名(别名)&#xff1a;…

视频汇聚平台EasyCVR如何构建智慧农业监控监管系统?

视频汇聚平台EasyCVR如何构建智慧农业监控监管系统?现代农业的迅速发展中,集成监控管理系统已成为提高农业生产效率和优化管理的关键工具。EasyCVR视频汇聚平台作为一个具有高度可扩展性、灵活的视频处理能力和便捷的…

一套自用的git提交规范,可清晰的识别到关联的任务/bug - 实践

一套自用的git提交规范,可清晰的识别到关联的任务/bug - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Con…

学做ps的软件的网站有哪些内容石家庄网站建设王道下拉棒

博主介绍&#xff1a;黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者&#xff0c;CSDN博客专家&#xff0c;在线教育专家&#xff0c;CSDN钻石讲师&#xff1b;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程&#xff…

高平市规建设局网站学生个人网站布局

这年头&#xff0c;在职场不但要会做&#xff0c;还要会说。 会说还不能平铺直叙的说&#xff0c;还要能把普通的工作说出话来&#xff0c;这就需要一些“考究”的用词。尤其是在某些头部企业的带领下&#xff0c;业务不够、产品不行、解决方案不够新&#xff0c;就用华丽的辞…

撕开厂商锁定黑箱:MyEMS 如何用开源代码夺回能源管理的 “自主控制权”?

在能源管理数字化浪潮中,许多企业曾满怀期待引入专业系统,却最终陷入深深的困境:系统建成之日,竟是受制于人之时。高昂的许可费、昂贵的定制开发、无休止的升级服务费、封闭的数据格式……这些看似专业的能源管理系…

继续 Vibe Coding 撸工具:Markdown写作 + 一键发布

又是感谢Vibe Coding的一天,最近尝试用 CodyBuddy 来重构一下之前的文章发布工具OpenWrite,经过一周的迭代,现在基本差不多恢复之前80%的功能了。如果你跟我一样,平时写点东西,又讨厌自己的文章被别人搬运,那么可…

C造桥与砍树

链接 题意: 有n个带权的点以及参数k,要求生成一个最小生成树,每个点之间的边权为两个点权之和模k的结果 思路: 对所有权值模k后 发现对于一个权值为val的结点u,链接它的最优结点是 现在还没进入生成树的 (权值最…

基于衍射神经网络的光学高速粒子分类体系A1(未做完)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Keil uVision5 MDK 5.42安装教程(支持ARM Cortex全系列开发)

软件介绍 Keil uVision5 MDK 5.42是ARM公司推出的嵌入式处理器集成开发环境最新版本,专为Cortex-M、Cortex-A、ARM7、ARM9等ARM内核处理器设计。该版本集成ARM Compiler编译器、μVision IDE调试器及Flash烧写模块,支…

2024 ICPC ECfinal E

E. Corrupted Scoreboard Log 大模拟,暴搜。 预处理出 \(0\sim 299\) 和 \(1\sim 100\) 的组合字符串,后续处理出每个 \(\text{try}\) 前面的数字就能得到是哪些组合了,注意 \(\text{22tries}\) 这种还可以拆成 \(\…

自助建子站wordpress粉色主题

1、引言 用SHT30测温湿度&#xff0c;SHT30是I2C通信总线&#xff0c;具体信息去看Datasheet文档&#xff1a;https://pdf1.alldatasheet.com/datasheet-pdf/view/897974/ETC2/SHT30.html。操作系统是Linux&#xff0c;机器是CM3计算板&#xff0c;当然也可以是树莓派和其他主…

从Void到Task<PublishAggregateResult>:一次服务方法返回类型重构的纠结与决策

今天原本想美美地完成UI层与Core层通过消息总线实现博客发布的功能。一切都很顺利,直到我重构到 PublishBlog 方法,准备为ApplicationService 写事件处理逻辑时,不然发现不对劲——“不兑!等等,我该怎么把发布结果…

LVGL移植到STM32F4出现无法运行的问题

跟着网上的教程一步步移植LVGL v8.3到STM32F407VET6上,虽然能成功运行,但是在刷新屏幕可能会出现:只刷新了一部分屏幕 整个屏幕都会卡死查阅了很多资料都没解决,在使用别人的Keil工程时,发现代码的优化等级是-O1,…

网站建设的原因有什么给个网址2021年能看的

环境 Windows 11 家庭中文版git version 2.41.0.windows.1 问题情况 在使用 “命令行终端” 和 “Git Bash” 在本地Git仓库敲击命令时&#xff0c;对中文名称文件显示一连串的数字&#xff0c;如下所示&#xff1a;这种情况通常是由于字符编码设置不正确所引起的 解决办法 设置…

如何选择做网站网易企业邮箱忘记密码

&bc_control spec_bdy_width 此参数指定用于边界过渡的格点总行数&#xff0c;默认值为5。此参数只用于真实大气方案。参数的大小至少为spec_zone 和 relax_zone的和。 spec_zone 指定区域(specified zone)的格点数&#xff0c;默认值为 1。指定边条件时起作用。 relax…

网站地图提交入口班级优化大师电脑版

1,先把报错SQL语句拿出来执行&#xff0c;看看是不是报的这个错 ORA-01830: 日期格式图片在转换整个输入字符串之前结束 2&#xff0c;然后查看默认日期格式是不是“YYYY-MM-DD HH24:MI:SS”&#xff08;正确格式&#xff09;。&#xff1b; 执行&#xff1a; SELECT * FRO…

题目记录(Before NOIP2025 ver)

T1. Beautiful Sequence Unraveling 定义 \(dp_{i,j}\) 表示长度为 \(i\),值域在 \([1,j]\) 之间的好序列的个数。发现好序列不好刻画,所以转化为所有序列的数量减去不是好序列的数量。前者很显然,即 \(i^j\)。接下…

专业修复sqlserver master 数据库损坏。

例如一下错误 在重做数据库“master”中的日志记录操作时,日志记录 ID (57081:184:2) 出错。通常,特定故障以前会在操作系统错误日志中记录为错误。请从完整备份还原数据库,或者修复该数据库。 无法在数据库“maste…

78-材料可视化-折线图

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …