"模式"对于django中的数据库锁定对象

时间:2014-08-06 15:42:13

标签: python django

我的django代码中有这种模式,因为我需要对用户对象进行数据库级锁定,以防我需要修改它(POST或DELETE操作)。 我基本上做的是将locked_until字段设置为(现在+ timedelta(即5分钟))如果此locked_until小于当前时间,则认为对象已锁定。这给了我一个故障保护,以防一个操作以某种方式结束它不应该(或程序死亡)并使对象锁定。

但这种模式似乎有点令人困惑。你认为某些东西(即装饰器)可以让它更容易阅读吗?

感谢

def get_user(user_id, lock=True):
    if lock:
        with transaction.atomic():
            user = user.objects.select_for_update().get(user_id=user_id)                                
            if user.locked_until >= timezone.now():                                                   
                raise LockedException()                                                              
            elif user.locked_until != settings.MIN_DATE:                                              
                logger.warn('user_id=%(user_id)s, msg="user was left locked"', {'user_id': user.user_id}) 

            user.locked_until = (timezone.now() +
                                        timezone.timedelta(seconds=settings.LOCK_TIMEOUT))
            user.save()
    else:
        user = user.objects.get(user_id=user_id)

    return user


def user(request, user_id=None):
    user = None
    if user_id:
        try:
            user = get_user(user_id, lock=(request.method != 'GET'))
        except LockedException:
            logger.warn('op=user, msg="user is locked"')
            return HttpResponseServerError(jsonMessage('user=%(user)s is locked' % {'user': user_id}))
        except user.DoesNotExist:
            logger.warn('op=user, msg="user doesn\'t exist"')
            return HttpResponseNotFound(jsonMessage('invalid user=%(user)s' % {'user': user_id}))
        except Exception, e:
            logger.error('op=user, msg="unknown error", msg=%(exception)s',
                         {'exception': e.message})
            return HttpResponseServerError(jsonMessage(e.message))


    if request.method == 'GET':
        #...
        #do GET stuff...
        #...
    elif request.method == 'POST':
        try:
            #...
            #do POST stuff...
            #...
        finally:
            if user:
                user.locked_until = settings.MIN_DATE
                user.save()
    elif request.method == 'DELETE':
        try:
            #...
            #do DELETE stuff...
            #...
        finally:
            if user:
                user.locked_until = settings.MIN_DATE
                user.save()

1 个答案:

答案 0 :(得分:0)

更容易阅读的是上下文管理器。这可能会影响你的try-finally条款。

#...
if request.method == 'GET':
    #...
    #do GET stuff...
    #...
elif request.method == 'POST':
    with locked_user(user_id) as user:
        #...
        #do POST stuff...
        #...
elif request.method == 'DELETE':
    with locked_user(user_id) as user:
        #...
        #do DELETE stuff...
        #...