Django model 层之事务管理总结

Django model 层之事务管理总结

by:授客 QQ1033553122

 

实践环境

Python版本:python-3.4.0.amd64

下载地址:https://www.python.org/downloads/release/python-340/

 

 

Win7 64位

 

Django  1.11.4

下载地址:https://www.djangoproject.com/download/

 

 

管理数据库事务

Django默认事务机制

Django默认事务自动提交模式。每个查询都会被立即提交到数据量,除非查询是未于事务之内。

 

 

显示控制事务

atomic(using=None, savepoint=True)

 

用法1:把atomic当装饰器使用

from django.db import transaction

 

@transaction.atmoic

def viewfunc(request):

    # 函数中的代码将放在同一个事务中,一起执行

    do_stuff()

 

用法2:把atomic当上下文管理器使用

from django.db import transaction

 

def viewfunc(request):

do_stuff() # 这部分代码会采用Django默认事务管理模式-自动提交

 

with transaction.atomic():

    # 以下代码(with作用范围内的),将放在同一个事务中,一起执行

    do_more_stuff()

 

 

可以把atomic封装在一个try/except语句块内

 

from django.db import transaction

 

def viewfunc(request):

create_parent()

 

    try:

    with transaction.atomic():

        do_stuff()

    except Exception as e:

    handle_exception()

 

add_children()

 

说明:

如果try:...except 语句块发生异常,那么do_stuff()所作的改变将被回滚。但是create_parent(),add_children()所作的改变不会被回滚。

 

特别要注意,不要在with transaction.atomic():作用范围内捕获异常,否则会有意想不到的后果,因为Django是根据未捕获的数据库异常来判断并执行回滚的

 

处于性能考虑,尽量保证事务尽可能的小,特别是在atomic()内放置处理需要耗时较长的程序代码。

 

参考链接:

https://docs.djangoproject.com/en/2.0/topics/db/transactions/#controlling-transactions-explicitly

 

 

事务之后的操作

on_commit(func, using=None)

 

from django.db import transaction

def do_something():

    pass  # send a mail, invalidate a cache, fire off a Celery task, etc.

 

    transaction.on_commit(do_something)

 

也可以传递匿名函数

transaction.on_commit(lambda: some_celery_task.delay('arg1'))

 

 

注意:on_commit中的回调函数仅在前面的事务成功提交后才被执行,否则会被忽略。

 

保存点(savepoint)

 

with transaction.atomic():  # Outer atomic, start a new transaction

    transaction.on_commit(foo)

 

    with transaction.atomic():  # Inner atomic block, create a savepoint

        transaction.on_commit(bar)

 

# foo() 和 bar() 将在离开最外层语句块时被调用。

with transaction.atomic():  # Outer atomic, start a new transaction

    transaction.on_commit(foo)

 

    try:

        with transaction.atomic():  # Inner atomic block, create a savepoint

            transaction.on_commit(bar)

            raise SomeError()  # Raising an exception - abort the savepoint

    except SomeError:

        pass

 

# foo() will be called, but not bar()

 

 

https://docs.djangoproject.com/en/2.0/topics/db/transactions/

 

 

posted @ 2020-08-16 20:25  授客  阅读(605)  评论(0编辑  收藏  举报