♻️(backend) move lock in create_for_owner action in the serializer

For the create_for_owner action, all the db operation are made in the
serializer. But the lock of the table was acquired in the viewsets, lot
of operation are made between the lock is made and the insert in db. We
move the lock operation closer to the insert in the database. We wrap it
in a transaction to release the lock once the commit made.
This commit is contained in:
Manuel Raynaud 2026-04-02 11:34:49 +02:00 committed by GitHub
parent 756cf82678
commit 8df86e6dc8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 14 additions and 13 deletions

View file

@ -7,6 +7,7 @@ from base64 import b64decode
from os.path import splitext
from django.conf import settings
from django.db import connection, transaction
from django.db.models import Q
from django.utils.functional import lazy
from django.utils.text import slugify
@ -505,11 +506,19 @@ class ServerCreateDocumentSerializer(serializers.Serializer):
{"content": ["Could not convert content"]}
) from err
document = models.Document.add_root(
title=validated_data["title"],
content=document_content,
creator=user,
)
with transaction.atomic():
# locks the table to ensure safe concurrent access
with connection.cursor() as cursor:
cursor.execute(
f'LOCK TABLE "{models.Document._meta.db_table}" ' # noqa: SLF001
"IN SHARE ROW EXCLUSIVE MODE;"
)
document = models.Document.add_root(
title=validated_data["title"],
content=document_content,
creator=user,
)
if user:
# Associate the document with the pre-existing user

View file

@ -887,19 +887,11 @@ class DocumentViewSet(
permission_classes=[],
url_path="create-for-owner",
)
@transaction.atomic
def create_for_owner(self, request):
"""
Create a document on behalf of a specified owner (pre-existing user or invited).
"""
# locks the table to ensure safe concurrent access
with connection.cursor() as cursor:
cursor.execute(
f'LOCK TABLE "{models.Document._meta.db_table}" ' # noqa: SLF001
"IN SHARE ROW EXCLUSIVE MODE;"
)
# Deserialize and validate the data
serializer = serializers.ServerCreateDocumentSerializer(data=request.data)
if not serializer.is_valid():