From d1aed7c9ea1dd75d5560d2954e866fd07d1f2e8c Mon Sep 17 00:00:00 2001 From: BaiJiangJie <32935519+BaiJiangJie@users.noreply.github.com> Date: Fri, 17 Jul 2020 15:26:12 +0800 Subject: [PATCH] =?UTF-8?q?fix(asset=5Fuser):=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=88=9B=E5=BB=BAAuthBook=E5=AF=B9=E8=B1=A1=E9=94=81=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=EF=BC=8C=E4=BD=BF=E7=94=A8select=5Ffor=5Fupdate?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2redis=5Flock=20(#4351)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(authbook): 修改创建AuthBook对象锁机制,解决并发操作堵塞问题 * fix(asset_user): 修改创建AuthBook对象锁机制,使用select_for_update替换redis_lock * fix(asset_user): 修改创建AuthBook对象锁机制,使用select_for_update替换redis_lock2 * fix(asset_user): 修改创建AuthBook对象锁机制,使用select_for_update替换redis_lock3 --- apps/assets/models/authbook.py | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/apps/assets/models/authbook.py b/apps/assets/models/authbook.py index 052b83a64..7d0a3f472 100644 --- a/apps/assets/models/authbook.py +++ b/apps/assets/models/authbook.py @@ -3,7 +3,6 @@ from django.db import models, transaction from django.db.models import Max -from django.core.cache import cache from django.utils.translation import ugettext_lazy as _ from orgs.mixins.models import OrgManager @@ -59,19 +58,17 @@ class AuthBook(BaseUser): """ 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 + with transaction.atomic(): + # 使用select_for_update限制并发创建相同的username、asset条目 + instances = cls.objects.select_for_update().filter(username=username, asset=asset) + instances.filter(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 def connectivity(self):