1. transaction.on_commit()이란?

Django에서 데이터베이스 트랜잭션이 성공적으로 커밋된 직후 어떤 작업을 실행하고 싶을 때 사용하는 콜백 등록 메서드입니다.

from django.db import transaction

transaction.on_commit(my_function)

이 코드를 실행하면, 현재 트랜잭션이 성공적으로 끝난 이후에 my_function()이 실행됩니다.

Django transaction.on_commit conceptual image


2. 어떤 상황에서 사용하는가?

상황 사용 여부
DB에 저장이 확실히 끝난 후 무언가 실행하고 싶을 때 ✅ 적합
Celery task를 트랜잭션 이후에 실행하고 싶을 때 ✅ 적합
외부 API 호출, 캐시 갱신 등 ✅ 적합
트랜잭션 밖에서 호출 순서가 중요하지 않을 때 ❌ 부적합

3. 핵심 개념

  • on_commit()"현재 실행 중인 트랜잭션이 있을 때만" 의미가 있습니다.
  • 트랜잭션이 없다면, 콜백은 즉시 실행됩니다!

4. 잘못된 예시

def my_view(request):
    def notify():
        print("실행됨!")

    transaction.on_commit(notify)  # 트랜잭션이 없으므로 즉시 실행됨!

5. 올바른 사용 예시

from django.db import transaction

def my_view(request):
    with transaction.atomic():
        post = Post.objects.create(...)
        post.categories.add(...)

        def translate():
            translate_post.delay(post.id)

        transaction.on_commit(translate)

위 예시에서는 post 생성 및 카테고리 추가가 모두 완료된 후에만 translate()이 실행됩니다.


6. 왜 중요한가?

많은 개발자들이 아래를 혼동합니다:

  • ORM의 create(), add()는 실제로 커밋된 게 아님
  • 커밋 전에는 모두 "논리적 저장" 상태
  • Celery task는 별도 프로세스에서 실행되므로,
  • 커밋 전에 실행되면 불완전한 데이터를 참조하게 됨

7. Celery와 함께 쓰는 이상적인 예시

@shared_task
def post_finalize_task(post_id, categories, tags):
    post = Post.objects.get(id=post_id)

    with transaction.atomic():
        for name in categories:
            cat, _ = Category.objects.get_or_create(name=name)
            post.categories.add(cat)

        for name in tags:
            tag, _ = Tag.objects.get_or_create(name=name)
            post.tags.add(tag)

        def schedule_translation():
            translate_post.delay(post.id)

        transaction.on_commit(schedule_translation)

이 구조는 카테고리/태그 저장이 확실히 된 뒤에만 translate_post task를 실행하도록 보장합니다.


8. 요약 정리

개념 설명
언제 실행됨? 트랜잭션이 성공적으로 커밋된 직후
실패 시? rollback되면 절대 실행되지 않음
트랜잭션 없으면? 즉시 실행됨 (주의!)
사용 위치 with transaction.atomic() 블록 내부
활용 예시 Celery task 실행, 알림 발송, 캐시 반영 등

9. Jesse의 코멘트

transaction.on_commit()은 단순한 지연 실행이 아닙니다.
트랜잭션이 성공한 경우에만 실행하겠다는 개발자의 명확한 의도 표현이며,
ORM과 비동기 처리를 함께 사용할 때, 데이터 무결성을 지키기 위한 필수 도구입니다.