我的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()
答案 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...
#...