Browse Source

[Update] 创建AuthBook对象的方法从ModelManager中移动到Model中,保留原生的对象create方法;同时添加事务处理;

pull/3829/head
Bai 5 years ago
parent
commit
4583beaec0
  1. 2
      apps/assets/backends/manager.py
  2. 52
      apps/assets/models/authbook.py

2
apps/assets/backends/manager.py

@ -155,7 +155,7 @@ class AssetUserManager:
@staticmethod @staticmethod
def create(**kwargs): def create(**kwargs):
# 使用create方法创建AuthBook对象,解决并发创建问题(添加锁机制) # 使用create方法创建AuthBook对象,解决并发创建问题(添加锁机制)
authbook = AuthBook.objects.create(**kwargs) authbook = AuthBook.create(**kwargs)
return authbook return authbook
def __getattr__(self, item): def __getattr__(self, item):

52
apps/assets/models/authbook.py

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
from django.db import models from django.db import models, transaction
from django.db.models import Max from django.db.models import Max
from django.core.cache import cache from django.core.cache import cache
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -18,25 +18,7 @@ class AuthBookQuerySet(models.QuerySet):
class AuthBookManager(OrgManager): class AuthBookManager(OrgManager):
pass
def get_max_version(self, username, asset):
version_max = self.filter(username=username, asset=asset)\
.aggregate(Max('version'))
version_max = version_max['version__max'] or 0
return version_max
def create(self, **kwargs):
username = kwargs['username']
asset = kwargs['asset']
key_lock = 'KEY_LOCK_CREATE_AUTH_BOOK_{}_{}'.format(username, asset.id)
with cache.lock(key_lock, expire=60):
self.filter(username=username, asset=asset, is_latest=True)\
.update(is_latest=False)
max_version = self.get_max_version(username, asset)
kwargs['version'] = max_version + 1
kwargs['is_latest'] = True
obj = super().create(**kwargs)
return obj
class AuthBook(BaseUser): class AuthBook(BaseUser):
@ -59,6 +41,36 @@ class AuthBook(BaseUser):
def generate_id_with_asset(self, asset): def generate_id_with_asset(self, asset):
return self.id return self.id
@classmethod
def get_max_version(cls, username, asset):
version_max = cls.objects.filter(username=username, asset=asset) \
.aggregate(Max('version'))
version_max = version_max['version__max'] or 0
return version_max
@classmethod
def create(cls, **kwargs):
"""
使用并发锁机制创建AuthBook对象, (主要针对并发创建 username, asset 相同的对象时)
并更新其他对象的 is_latest=False (其他对象: 与当前对象的 username, asset 相同)
同时设置自己的 is_latest=True, version=max_version + 1
"""
username = kwargs['username']
asset = kwargs['asset']
key_lock = 'KEY_LOCK_CREATE_AUTH_BOOK_{}_{}'.format(username, asset.id)
with cache.lock(key_lock):
with transaction.atomic():
cls.objects.filter(
username=username, asset=asset, is_latest=True
).update(is_latest=False)
max_version = cls.get_max_version(username, asset)
kwargs.update({
'version': max_version + 1,
'is_latest': True
})
obj = cls.objects.create(**kwargs)
return obj
@property @property
def connectivity(self): def connectivity(self):
return self.get_asset_connectivity(self.asset) return self.get_asset_connectivity(self.asset)

Loading…
Cancel
Save