[DRF] - Transaction

오동훈·2022년 11월 13일
0

Django

목록 보기
10/23
post-custom-banner

1. Transaction

데이터베이스 트랜잭션(Database Transction)은 데이터베이스 관리 시스템 또는 유사한 시스템에서 상호작용의 단위입니다. 여기서 유사한 시스템이란 트랜잭션이 성공과 실패가 분명하고 상호 독립적이며, 일관되고 믿을 수 있는 시스템을 의미합니다.

이론적으로 데이터베이스 시스템은 각각의 트랜잭션에 대해 원자성(Atomicity), 일관성(Consistency), 고립성(Isolation), 영구성(Durability)을 보장합니다. 이 성질들의 첫 글자를 따 ACID라 부릅니다.

다시 말해 트랜잭션은 데이터베이스 내에서 한꺼번에 수행되어야 할 일련의 연산들입니다. 간단하게 말해서 전부 성공하거나 전부 실패되거나 둘 중 하나의 작업을 수행합니다. 트랜잭션의 모든 연산은 반드시 한꺼번에 완료가 되야 하며 그렇지 않은 경우에는 한꺼번에 취소되어야 하는 원자성을 가지고 있습니다.

한꺼번에 완료가 된 경우에는 COMMIT을 호출해 작업 결과를 데이터베이스에 반영합니다. 취소가 되거나 문제가 발생한 경우에는 ROLLBACK을 호출하고 작업 결과를 모두 취소하여 데이터베이스에 영향을 미치지 않게 됩니다.

2. 사용 예

크게 은행의 돈 이체 작업은 트랙잭션을 이용한 작업이라고 생각하면 됩니다.

돈을 이체했을 때 내 통장은 이체한 금액만큼 차감되고, 상대방 통장은 이체한 금액만큼 증액되어야 합니다.
하지만 이체를 실행했을 때 상대방 통장은 증액되었는데, 내 통장에 그만한 금액이 존재하지 않다면 난감하겠죠?

그래서 이러한 작업을 수행할 때 트랜잭션을 이용해 전부 성공하거나 전부 실패되거나 둘 중 하나의 작업을 수행되게끔 합니다.

3. Django에서의 사용법

Django에서 Transaction 사용 법은 크게 2가지가 있습니다.

1. decorator

decorator는 하나의 함수입니다. 사용자가 코드를 간결하고 편리하게 쓸 목적으로 사용하고 있습니다.

transaction을 필요로 하는 코드 위에 @transaction.atomic를 작성해주면 끝입니다!

from django.db import transaction

@transaction.atomic
def viewfunc(request):
    # This code executes inside a transaction.
    do_stuff()

2. context manager

컨텍스트 매니저는 원하는 타이밍에 정확하게 리소스를 할당하고 제공하는 역할을 합니다. 가장 많이 사용되는 컨텍스트 매니저는 with 문입니다.

Transaction을 필요로 하는 구간에서 with transaction.atomic()를 선언해주면 끝입니다!

from django.db import transaction

def viewfunc(request):
    # This code executes in autocommit mode (Django's default).
    do_stuff()

    with transaction.atomic():
        # This code executes inside a transaction.
        do_more_stuff()

하지만 context manager를 이용하는 경우 오류가 일어났을 때 알 수 있는 방법이 없다는 것을 알 수 있습니다. Transaction이 성공 및 실패 2가지의 결과로 나타나게 될텐데 우리 눈으로 확인할 수 있는 것은 없습니다. 따라서 우리는 알 필요가 있기 때문에 try-except를 랩핑해 같이 사용하곤 합니다.

3. context manager + try-except

try-except 블록으로 래핑하면 무결성 오류를 자연스럽게 처리할 수 있습니다.

from django.db import IntegrityError, transaction

@transaction.atomic
def viewfunc(request):
    create_parent()

    try:
        with transaction.atomic():
            generate_relationships()
    except IntegrityError:
        handle_exception()

    add_children()

참고 자료 📩

Django - Transaction 공식 문서

profile
삽질의 기록들🐥
post-custom-banner

0개의 댓글