Django事务的使用

该博客介绍了如何在Django中使用`transaction.atomic`装饰器进行事务管理,确保一组数据库操作在异常情况下能全部回滚,保持数据一致性。通过设置保存点,可以在出现错误时仅回滚到特定保存点,而正常情况下则提交事务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

from django.db import transaction # 导入事务

class XXX(APIView):

    @transaction.atomic
    # transaction.atomic装饰器可以保证该函数中所有的数据库操作都在一个事务中。
    def XXX(self,request):
    	 # 开启事务
            with transaction.atomic ():
                # 设置事务保存点
                s1 = transaction.savepoint ( )  # 可以设置多个保存点
                try:
                    # 数据库操作
                    for i in eval (Works.objects.filter (id=wid).first ( ).next_id):
                        Task.objects.filter(uid=i).update(state=state, opinion=opinion)
                except Exception as e:
                    # 事务回滚 (如果发生异常, 就回滚事务)
                    transaction.savepoint_rollback (s1)
                else:
                    # 提交事务 (如果没有异常,就提交事务)
                    transaction.savepoint_commit (s1)

导包transaction

设置该函数中的所有数据库操作在同一个事物中,第一个数据库操作1即使成功保存到数据库中,只要第2个数据操作失败,那么所有该段代码所有涉及的数据库操作都会更改回滚到原来。

@transaction.atomic
transaction.atomic装饰器可以保证该函数中所有的数据库操作都在一个事务中。

with transaction.atomic()
设置事务保存点并开启事务

s1 = transaction.savepoint() # 开启事务设置事务保存点
数据库读写操作

操作1

操作2

失败回滚事务(条件:任意一个操作失败,数据库操作发生异常,回滚到设置的事务保存点)
transaction.savepoint_rollback(s1)

成功(条件:操作1和2都成功,提交事务)

transaction.savepoint_commit(sid) # 如果没有异常,成功提交事务

### Django使用事务处理文件上传 在 Django 应用程序中,为了确保数据的一致性和完整性,在涉及数据库写入操作的同时处理文件上传时应考虑使用事务管理。通过 `transaction.atomic()` 上下文管理器可以实现这一点。 当涉及到文件存储和数据库记录创建之间的同步问题时,推荐的做法是在同一个原子性事务内完成这两者。这意味着如果任何部分失败,则整个过程都将回滚,从而保持系统的稳定状态。 #### 实现方法 打开项目中的视图函数所在文件(通常位于`views.py`),并导入必要的模块: ```python from django.db import transaction from django.core.files.storage import default_storage ``` 定义一个用于接收文件并通过表单保存至模型实例的方法,并将其包裹于 `transaction.atomic()` 块之中: ```python @transaction.atomic def handle_file_upload(request): if request.method == 'POST': form = MyModelForm(request.POST, request.FILES) if form.is_valid(): instance = form.save(commit=False) # 处理文件上传逻辑 uploaded_file = request.FILES['file_field'] saved_path = default_storage.save('path/to/save/' + uploaded_file.name, uploaded_file) try: with transaction.atomic(): # 开始一个新的嵌套事务 # 更新 model 对象属性 instance.file_path = saved_path # 将更改提交到数据库 instance.save() # 可选:在此处继续其他依赖于此成功的操作 except Exception as e: # 如果发生异常则会触发回滚机制 raise TransactionManagementError(f"An error occurred while saving the file or database record: {e}") return redirect('success_url') else: form = MyModelForm() context = {'form': form} return render(request, 'template.html', context) ``` 上述代码展示了如何在一个请求周期里安全地执行文件上传以及相应的数据库条目更新。这里的关键在于利用了两次调用 `transaction.atomic()`: 第一次是为了覆盖整个视图函数;第二次则是针对可能引发错误的具体业务逻辑进行了更细粒度的控制[^1]。 需要注意的是,对于大型文件或长时间运行的任务来说,应该评估是否适合采用这种方式,因为这可能会占用较多资源并且影响性能。另外,考虑到并发情况下的竞争条件,建议仔细设计应用程序的工作流以避免潜在的风险。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值