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()上下文管理器,你可以清晰地界定事务的范围。

Django事务的更多相关文章

  1. python 全栈开发,Day118(django事务,闭包,客户管理,教学管理,权限应用)

    昨日内容回顾 一.django事务 什么是事务 一系列将要发生或正在发生的连续操作. 作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行. 事务处理可以确保除非事务性单元内的所有操 ...

  2. Django 事务

    Django事务 事务是通过将一组相关操作组合为一个,要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠.事务具有4个特性:原子性.一致性.隔离性.持久性. 默认情况下,在Djang ...

  3. Django框架10 /sweetalert插件、django事务和锁、中间件、django请求生命周期

    Django框架10 /sweetalert插件.django事务和锁.中间件.django请求生命周期 目录 Django框架10 /sweetalert插件.django事务和锁.中间件.djan ...

  4. Django 事务操作

    如何在Django中进行事务操作 案例: 客户A要给客户B转一笔钱,这个在数据库中需要进行两步: 1.客户A减钱 2.客户B加钱 如果在第一步结束后,服务器出现异常,停下了,第二步没有进行,如果数据库 ...

  5. django 事务错误 -- Transaction managed block ended with pending COMMIT/ROLLBACK

    Request Method: GET Request URL: http://192.168.128.111:8000/×××/××××/ Django Version: 1.4.8 Excepti ...

  6. django事务模式

    from django.db import transaction from django.db import transaction with transaction.atomic(): obj = ...

  7. django 事务踩坑

    with transaction.atomic(): save_id = transaction.savepoint() #xx.字段A ormg更新操作 #提交事务 transaction.save ...

  8. django中的事务管理

    在讲解之前首先来了解一下数据库中的事务. 什么是数据库中的事务? 热心网友回答: ():事务(Transaction)是并发控制的单位,是用户定义的一个操作序列.这些操作要么都做,要么都不做,是一个不 ...

  9. 关于Django Web应用架构设计开发的几个问题

    1.关于分层,做过传统JEE应用的同学肯定知道JEE应用会分很多个设计层.根据传统Web应用架构设计一般从上到下分这么几个层(太懒了,不画图了):Web前端层.Web后端交互层.业务层.基础数据设施层 ...

  10. python3之Django多数据库

    1.定义数据库 在django项目中, 一个工程中存在多个APP应用很常见:有时候希望不同的APP连接不同的数据库,这个时候需要建立多个数据库连接.在Django的setting中使用DATABASE ...

随机推荐

  1. 在华为云服务器上测试GCC for OpenEuler的特性

    前言 操作系统课程任务 探讨 GCC for openEuler 的特性和优势 什么是 GCC for openEuler? GCC for openEuler 基于开源 GCC-10.3 版本(GC ...

  2. C# 列表项下拉窗口宽度自适应

    /// <summary> /// 列表项下拉窗口宽度自适应 /// </summary> /// <param name="comboBox"> ...

  3. 精控Spring AI日志

    还在为 Spring AI 默认的日志抓狂吗?想看日志却看不到,一开 DEBUG 就刷屏... 别慌! 今天 NEO 带你解锁一个神级操作:自定义 Advisor,让你轻松掌控 AI 调用的每一个细节 ...

  4. base64编码文件下载

    比方说,我有一个bse64如下的编码文件: const base64Str = "UEsDBBQABgAIAAAAIQAykW9XZgEAAKUFAAATAAgCW0NvbnRlbnRfVH ...

  5. ETLCloud中如何使用Kettle组件

    ETLCloud中如何使用Kettle组件在当今数据驱动的时代,数据处理和分析已成为企业决策的关键.为了更高效地处理海量数据,ETL(Extract, Transform, Load)工具变得至关重要 ...

  6. SciTech-Chemistry(化学)-电解: 电化学之"Electroplating(电镀)"工艺及应用 + Switching Power(开关电源 可软件控制波形)

    Electroplating(电镀): Electroplating(电镀)是 "镀液的金属离子" 在外电场作用, 经 "电极反应" 还原成"金属原子 ...

  7. SciTech-Science: 纯色滤(分)光塑料片: 将光分解为BGR三原纯色(彩色CCD传感器原理) + “502熏显法”采集“指纹”与Glue胶水: 普通胶水是“胶”与“水”混合物因此不会黏上瓶子

    彩色滤(分)光塑料片: 将光分解为BGR三原纯色 彩色CCD传感器原理 透过 一张 彩色滤(分)光塑料片 可以分解出 光源的"与滤光片同颜色"的成份: 例如 "B(蓝色) ...

  8. Win11系统桌面没有此电脑的问题

    许多电脑基地的用户安装Windows11系统之后,发现自己的电脑上没有此电脑等这个图标,但是我们在日常使用电脑的时候最经常使用打开的就是这个这个此电脑的,那么我们要怎么把它调出来呢?下面技术员小编就带 ...

  9. 「GIS数据」下载全国的GeoJSON、shp格式数据(精确到乡镇街道级)-2024年12月更新

    发现个可以免费下载全国 geojson 数据的网站,推荐一下.支持全国.省级.市级.区/县级.街道/乡镇级以及各级的联动数据,支持导入矢量地图渲染框架中使用,例如:D3.Echarts等 geojso ...

  10. ​​SBOM(软件物料清单)—— 软件供应链安全的“成分说明书”​

    1. 概述 现代软件都是组装的而非纯自研.随着开源组件在数字化应用中的使用比例越来越高,混源开发已成为当前业内主流开发方式.开源组件的引入虽然加快了软件开发效率,但同时将开源安全问题引入了整个软件供应 ...