Django ORM 事务 回滚

数据库事务

在保存订单数据中,涉及到多张表(OrderInfo、OrderGoods、SKU)的数据修改,对这些数据的修改应该是一个整体事务,即要么一起成功,要么一起失败。

Django中对于数据库的事务,默认每执行一句数据库操作,便会自动提交。我们需要在保存订单中自己控制数据库事务的执行流程。

在Django中可以通过django.db.transaction模块提供的atomic来定义一个事务,atomic提供两种用法

整体回滚

装饰器用法
所有的数据库更新操作都会在一个事务中执行,如果事务中任何一个环节出现错误,都会回滚整个事务。
此方案整个view都会在事务之中,所有对数据库的操作都是原子性的。

from django.db import transaction

# open a transaction
@transaction.atomic                #装饰器格式
def func_views(request):
         do_something()    
         a = A()              #实例化数据库模型
         try:
            a.save()
         except DatabaseError:
            pass

with语句用法

事务可以在代码中的任意地方开启,对于事务开启前的数据库操作是必定会执行的,事务开启后的数据库操作一旦出现错误就会回滚。

from django.db import transaction

 
def func_views(request):
    try:
        with transaction.atomic():      #上下文格式,可以在python代码的任何位置使用
            a = A()
            a.save()
            #raise DatabaseError     #测试用,检测是否能捕捉错误
    except DatabaseError:     # 自动回滚,不需要任何操作
            pass

保存点Savepoint(断点回滚)

在Django中,还提供了保存点的支持,可以在事务中创建保存点来记录数据的特定状态,数据库出现错误时,可以恢复到数据保存点的状态
保存点是事务中的标记,从原理实现上来说是一个类似存储结构的类。可以回滚部分事务,而不是完整事务,同时会保存部分事务。python后端程序可以使用保存点。

一旦打开事务atomic(),就会构建一系列等待提交或回滚的数据库操作。通常,如果发出回滚命令,则会回滚整个事务。保存点则提供了执行细粒度回滚的功能,而不是将执行的完全回滚transaction.rollback()。

工作原理:savepoint通过对返回sid后面的将要执行的数据库操作进行计数,并保存在内置的列表中,当对数据库数据库进行操作时遇到错误而中断,根据sid寻找之前的保存点并回滚数据,并将这个操作从列表中删除。

from django.db import transaction

# 创建保存点
save_id = transaction.savepoint()  

# 回滚到保存点
transaction.savepoint_rollback(save_id)

# 提交从保存点到当前状态的所有数据库事务操作
transaction.savepoint_commit(save_id)

# 重置用于生成唯一保存点ID的计数器
clean_savepoints(using = None)

# 这些函数中的每一个都接受一个using参数,该参数是数据库的名称。如果using未提供参数,则# 使用"default"默认数据库。

你可能感兴趣的:(python,Django+Redis,django,python,后端)