데이터베이스 트랜잭션(Database Transction)은 데이터베이스 관리 시스템 또는 유사한 시스템에서 상호작용의 단위입니다. 여기서 유사한 시스템이란 트랜잭션이 성공과 실패가 분명하고 상호 독립적이며, 일관되고 믿을 수 있는 시스템을 의미합니다.
이론적으로 데이터베이스 시스템은 각각의 트랜잭션에 대해 원자성(Atomicity), 일관성(Consistency), 고립성(Isolation), 영구성(Durability)을 보장합니다. 이 성질들의 첫 글자를 따 ACID라 부릅니다.
다시 말해 트랜잭션은 데이터베이스 내에서 한꺼번에 수행되어야 할 일련의 연산들입니다. 간단하게 말해서 전부 성공하거나 전부 실패되거나 둘 중 하나의 작업을 수행합니다. 트랜잭션의 모든 연산은 반드시 한꺼번에 완료가 되야 하며 그렇지 않은 경우에는 한꺼번에 취소되어야 하는 원자성을 가지고 있습니다.
한꺼번에 완료가 된 경우에는 COMMIT을 호출해 작업 결과를 데이터베이스에 반영합니다. 취소가 되거나 문제가 발생한 경우에는 ROLLBACK을 호출하고 작업 결과를 모두 취소하여 데이터베이스에 영향을 미치지 않게 됩니다.
크게 은행의 돈 이체 작업은 트랙잭션을 이용한 작업이라고 생각하면 됩니다.
돈을 이체했을 때 내 통장은 이체한 금액만큼 차감되고, 상대방 통장은 이체한 금액만큼 증액되어야 합니다.
하지만 이체를 실행했을 때 상대방 통장은 증액되었는데, 내 통장에 그만한 금액이 존재하지 않다면 난감하겠죠?
그래서 이러한 작업을 수행할 때 트랜잭션을 이용해 전부 성공하거나 전부 실패되거나 둘 중 하나의 작업을 수행되게끔 합니다.
Django에서 Transaction
사용 법은 크게 2가지가 있습니다.
decorator는 하나의 함수입니다. 사용자가 코드를 간결하고 편리하게 쓸 목적으로 사용하고 있습니다.
transaction을 필요로 하는 코드 위에 @transaction.atomic
를 작성해주면 끝입니다!
from django.db import transaction
@transaction.atomic
def viewfunc(request):
# This code executes inside a transaction.
do_stuff()
컨텍스트 매니저는 원하는 타이밍에 정확하게 리소스를 할당하고 제공하는 역할을 합니다. 가장 많이 사용되는 컨텍스트 매니저는 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
를 랩핑해 같이 사용하곤 합니다.
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()
참고 자료 📩