Django 事务回滚的具体实现可以分为两部分来讲解:数据库事务和Django事务。
在数据库中,事务是指作为一个单位执行的一系列操作。这些操作要么全部成功完成,要么全部失败回滚。数据库事务的四个性质是:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。这里我们着重讲解隔离性和持久性。
在MySQL中,当多个事务同时操作同一个表时,有可能会发生数据并发访问冲突的问题,例如读取到脏数据或不可重复读等问题。为了解决这个问题,MySQL通过锁机制来保证隔离性。
而持久性则保证数据提交之后的永久保存。即使系统崩溃或停电等极其异常情况,数据依然会保存在存储介质中。
Django中通过使用transaction装饰器或transaction.atomic()上下文管理器来增加事务性操作。主要使用了Python内置的在上下文完成前都可以被返回到之前状态的with语句。
使用 transaction.atomic() 上下文管理器的范例:
from django.db import transaction
@transaction.atomic
def viewfunc(request):
# Everything inside this block will run inside a transaction
# Ensure two records are created for both models or none:
object_a.save()
object_b.save()
当object_a保存失败后,Django会自动回滚事务,object_b的保存也会被回滚。
使用 @transaction.non_atomic_requests 装饰器的范例:
from django.db import transaction
@transaction.non_atomic_requests
def viewfunc(request):
# This code will run outside a transaction
...
例如有一个需求是在一个视图函数中对两个模型分别进行增删改查,需要保证对这两个模型的所有操作都成功或全部回滚。这里可以通过如下代码实现。
from django.http import HttpResponse
from django.db import transaction
@transaction.atomic
def my_view(request):
a = MyModelA.objects.create(field1='...')
b = MyModelB.objects.create(field1=a)
try:
a.field2 = 'foo'
a.save()
b.field2 = 'bar'
b.save()
1 / 0
except:
# Rollback
return HttpResponse(status=500)
return HttpResponse('OK')
这个示例中使用了 transaction.atomic() 上下文管理器来保证整个过程的事务性操作,使用try...except语句来进行错误处理。如果有错误发生,则会在except分支中进行回滚操作。如果没有错误,一切正常,就会在最后进行提交。
本文链接:http://task.lmcjl.com/news/18935.html