[Django] 장고 트랜잭션 활용하기

hukim·2020년 11월 8일
5

Django

목록 보기
8/12

장고에서 DB 트랜잭션을 이용하는 방법을 알아보겠습니다.

DB 트랜잭션에 관한 내용은 DataBase Transaction 이란?
이전에 작성했던 포스팅에 있습니다.

1. 데코레이터(decorator)를 이용한 트랜잭션

django에서 트랜잭션을 이용하는 가장 쉬운 방법으로는 데코레이터를 이용하는 방법입니다.
데코레이터를 이용하게 되면, 메소드 안에 코드를 삽입할 필요가 없습니다.
@transaction.atomic 이라는 데코레이터를 붙여주기만 합니다.
그리고 django 에서 기본적으로 제공해주기 때문에 별다른 모듈의 설치가 필요하지 않습니다.

가장 간단한 atomic(원자성)한 트랜잭션을 처리하기 위한 방법입니다.

from django.db import transaction

@transaction.atomic
def transaction_test(arg1, arg2):
	resume = Resume.objects.get(id = 1)
		
        resume.title        = 'title'
        resume.status       = 'status'
        resume.introduction = 'introduction'
        
        user_career = resume.usercareer_set.get(id = 1)
        user_career.company_name = 'company_name'
        
	# start transaction
    	resume.save()
    	user_career.save()
    	# end transaction

2. with 명령어를 이용한 트랜잭션

메소드 전체가 아닌 메소드의 일부분만 트랜잭션으로 묶어줄 필요가 있을 때 사용합니다.
트랜잭션으로 묶일 부분을 직접 지정해주면 되기 때문에 데코레이터와 마찬가지로 비교적 간단하게 처리가 가능합니다.

from django.db import transaction

def transaction_test(arg1, arg2):
	resume = Resume.objects.get(id = 1)
		
        resume.title        = 'title'
        resume.status       = 'status'
        resume.introduction = 'introduction'
        
        user_career = resume.usercareer_set.get(id = 1)
        user_career.company_name = 'company_name'
        
        education = resume.education_set.get(id = 1)
        education.university_name = 'university_name'
        
        resume.save() # 항상 save 처리, 예외 발생 시 에러 발생
        
        with transaction.atomic():
      	    # start transaction
            user_career.save()
            education.save()
            # end transaction

3. savepoint를 직접 지정해 주는 트랜잭션

위의 두 가지 방법의 경우, 메소드 내에서 exception이 발생하더라도 저절로 롤백이 되기 때문에
예외처리를 따로 해줄 필요는 없습니다. 하지만 3번의 경우에는 savepoint 및 commit 지점을 직접 지정해주기 때문에 예외처리 또한 별도로 처리되어야 합니다.

from django.db import transaction

def transaction_test(arg1, arg2):
	resume = Resume.objects.get(id = 1)
		
        resume.title        = 'title'
        resume.status       = 'status'
        resume.introduction = 'introduction'
        
        user_career = resume.usercareer_set.get(id = 1)
        user_career.company_name = 'company_name'
        
        education = resume.education_set.get(id = 1)
        education.university_name = 'university_name'
        
        resume.save() 
        
        sid = transaction.savepoint()
        
        # start transaction
        try:
            user_career.save()
            education.save()

            transaction.savepoint_commit(sid)
            # end transaction
        except Exception:
            transaction.savepoint_rollback(sid) # 트랜잭션 내에서 에러 발생시 롤백

0개의 댓글