Django ORM 数据完整性问题

django redis 2017年03月06日 星期一

django 中的事务使用

在很多的业务场景下,需要操作相关多个表,则会出现下面的情况,代码顺序执行下前部分操作正常如已save/update操作,后面出现exception,则会造成数据上的不完整。

"""
from django.db import transaction

# 装饰器使用
@transaction.atomic

# 上下文管理器使用
with transaction.atomic()
"""

参考官网:https://docs.djangoproject.com/en/1.10/topics/db/transactions/#controlling-transactions-explicitly

Django中get_or_create函数MultipleObjectsReturned Error

在项目的部署中 ,一般情况下都是nginx + uwsgi 模式,也一定会启动多进程,在并发的情况下,运气好的话(^_^),这种错误就会出现。

目前的做法是借助redis的锁去操作,这种方法适合一切多进程并发模式保护数据资源竞争的情况,如下情况:

"""

# get_or_create 函数获取/创建对象
m = Model.objects.get_or_create()

# 异常拦截模式获取/创建对象 
try:
    m = Model.objects.get()
exception Model.DoesNotExist:
    m = Model.objects.create()

# 对象数值属性更改
# 这种情况可以用F函数解决,详情
# https://docs.djangoproject.com/en/1.8/ref/models/expressions/#django.db.models.F
m.number += num
m.save()

"""
redis锁在PY中的用法也是相当的简单:
import redis

cli = redis.Redis()
with cli.lock('lock-key'):
    # 在管理器里做相应的操作
    do_staff()

关于redis锁的介绍可以参考 https://redis.io/topics/distlock,看源码【/python path/site-packages/redis/lock.py】是利用如下函数做的文章:

def setnx(self, name, value):
    "Set the value of key ``name`` to ``value`` if key doesn't exist"
    return self.execute_command('SETNX', name, value)

就酱了,  以上问题可以轻松解决, 以后还有什么问题再来更新 ...