diff --git a/apps/assets/api/node.py b/apps/assets/api/node.py index e832b83ba..c756e9efd 100644 --- a/apps/assets/api/node.py +++ b/apps/assets/api/node.py @@ -28,6 +28,7 @@ from ..tasks import ( ) from .. import serializers from .mixin import SerializeToTreeNodeMixin +from assets.locks import NodeAddChildrenLock logger = get_logger(__file__) @@ -114,15 +115,16 @@ class NodeChildrenApi(generics.ListCreateAPIView): return super().initial(request, *args, **kwargs) def perform_create(self, serializer): - data = serializer.validated_data - _id = data.get("id") - value = data.get("value") - if not value: - value = self.instance.get_next_child_preset_name() - node = self.instance.create_child(value=value, _id=_id) - # 避免查询 full value - node._full_value = node.value - serializer.instance = node + with NodeAddChildrenLock(self.instance): + data = serializer.validated_data + _id = data.get("id") + value = data.get("value") + if not value: + value = self.instance.get_next_child_preset_name() + node = self.instance.create_child(value=value, _id=_id) + # 避免查询 full value + node._full_value = node.value + serializer.instance = node def get_object(self): pk = self.kwargs.get('pk') or self.request.query_params.get('id') diff --git a/apps/assets/locks.py b/apps/assets/locks.py index bdab57080..ad36cd2e4 100644 --- a/apps/assets/locks.py +++ b/apps/assets/locks.py @@ -1,5 +1,6 @@ from orgs.utils import current_org from common.utils.lock import DistributedLock +from assets.models import Node class NodeTreeUpdateLock(DistributedLock): @@ -18,3 +19,11 @@ class NodeTreeUpdateLock(DistributedLock): def __init__(self): name = self.get_name() super().__init__(name=name, release_on_transaction_commit=True, reentrant=True) + + +class NodeAddChildrenLock(DistributedLock): + name_template = 'assets.node.add_children.' + + def __init__(self, node: Node): + name = self.name_template.format(org_id=node.org_id) + super().__init__(name=name, release_on_transaction_commit=True)