From: Robin Jarry Date: Mon, 8 Jun 2026 11:59:43 +0000 (+0200) Subject: parsemail: wrap parse_mail() in a single transaction X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=644cef7cd369abd39eba9523f8ecbc16d2ea4206;p=thirdparty%2Fpatchwork.git parsemail: wrap parse_mail() in a single transaction Wrap the entire parse_mail() call in transaction.atomic() so that all database writes from email parsing run inside a single transaction. The existing transaction.atomic() blocks inside parse_mail() become savepoints within this outer transaction. The series deduplication retry logic continues to work since savepoint rollbacks are scoped to their own savepoint. This also ensures that any on_commit() callbacks registered by signal handlers only fire after the full email has been parsed and all patch/series associations are committed. Signed-off-by: Robin Jarry Signed-off-by: Stephen Finucane Reviewed-by: Stephen Finucane [stephenfin: Slight tweaks to the release notes] --- diff --git a/patchwork/management/commands/parsemail.py b/patchwork/management/commands/parsemail.py index bcb257fe..2f90047a 100644 --- a/patchwork/management/commands/parsemail.py +++ b/patchwork/management/commands/parsemail.py @@ -8,6 +8,7 @@ import logging import sys from django.core.management import base +from django.db import transaction from patchwork.parser import parse_mail from patchwork.parser import DuplicateMailError @@ -57,7 +58,8 @@ class Command(base.BaseCommand): # broken email (ValueError): 1 (this could be noisy, if it's an issue # we could use a different return code) try: - result = parse_mail(mail, options['list_id']) + with transaction.atomic(): + result = parse_mail(mail, options['list_id']) if result is None: logger.warning('Nothing added to database') except DuplicateMailError as exc: diff --git a/releasenotes/notes/parsemail-transaction-d4e5f6g7h8i9j0k1.yaml b/releasenotes/notes/parsemail-transaction-d4e5f6g7h8i9j0k1.yaml new file mode 100644 index 00000000..5a224ca2 --- /dev/null +++ b/releasenotes/notes/parsemail-transaction-d4e5f6g7h8i9j0k1.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Wrap the entire ``parse_mail()`` function in a single database + transaction to prevent partial state from being visible to + concurrent readers.