Django使用数据库事务

记一次Django的事务应用

Posted by mengxun on January 24, 2019

需求

有个需求就是在Django的一次请求里,需要先创建域名,然后再创建配置信息并关联域名。

存在的问题

这种一次请求里涉及多次改变数据库的情况,一般都会有个大坑,就是前面的操作成功,然后中间出错导致后面的操作失败。比如域名的这个需求,如果域名创建成功,然后创建配置的时候出错,就会使得域名已存在但是配置不存在,如果想从头再来一次,很遗憾,域名是唯一的,不允许再创建相同的。

解决思路

这个时候数据库事务就能派上用场了,因为这些操作是连贯的,要么都成功,要么都失败,不允许一部分成功一部分失败。那么Django里怎么使用事务呢?

使用

Django里使用事务很方便,只需要在数据库配置里把 ATOMIC_REQUESTS 设置为True,就能对每个视图都开启事务:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'ATOMIC_REQUESTS': True
    }
}

如果不需要全局开启事务,也可以使用装饰器的方式来实现:

from django.db import transaction

@transaction.atomic
def viewfunc(request):
    # This code executes inside a transaction.
    do_stuff()

这样的话,就只针对具体的视图才开启事务。

更详细的可以参考:官方文档