TIL no.39 Django transaction

백선호·2021년 8월 8일
0

TIL

목록 보기
36/39
post-thumbnail

프로젝트에서 결제를 기능을 개발하던 중 결제가 진행되면 물건이 출고되었다고 변경해 주고 사용된 포인트를 차감해 저장해 주고 결제 전이었던 상태를 결제가 완료되었다고 상태를 변경해 주는 기능을 한 함수인에 구현해야 했다. 그런데 이처럼 한 함수 안에 여러 가지의 프로세스가 묶여서 한 기능으로 구현하고 싶었지만 계속 오류가 발생했는데 django의 트렌 섹션을 이용하여 간단하게 해결하였다.

transaction이란?

여러 개의 프로세스가 묶여져 마치 하나처럼 동작하는 방식이다. 성공 아니면 실패 두 가지 결과밖에 존재하지 않는다. 즉 데이터베이스를 저장하고 수정하는 여러 작업을 하나의 쿼리로 처리할 수 없기 때문에 여러 개의 쿼리로 나눠서 실행해야 하는데, 원자성 보장해 주기 위해 동일한 DB connection 객체를 사용하는 기술이다.

사용방법

django에서 트랜잭션을 django에서 기본적으로 제공해 주기 때문에 파이썬의 데코레이터 문법으로 사용하면 된다. 메서드 안에는 코드를 삽입할 필요가 없이"@transaction.atomic"이라는 데코레이터를 붙여주기만 하면 된다.

    @login
    @transaction.atomic
    def post(self, request):
        try:
            data   = json.loads(request.body)
            member = Member.objects.get(id=request.user.id)
            if member.points < data['total_price']:
                return JsonResponse({"MESSAGE":"INSUFFICIENT_POINTS"}, status=400)

            location=Location.objects.create(
                name         = data['name'],
                phone_number = data['phone_number'],
                email        = data.get('email', None),
                address      = data['address'],
                content      = data.get('content', None)
            )
            
            member.points = member.points - data['total_price']
            member.save()            

            order             = Order.objects.get(id=data['order_id'])
            order.location_id = location.id
            order.status_id   = 2
            order.save()

            order_items = OrderItem.objects.filter(order_id=data['order_id']) 
            for order_item in order_items:
                order_item.order_item_status_id = 2
                item                            = Item.objects.get(id=order_item.item_id)
                item.order_quantity             += order_item.quantity
                item.stock                      -= order_item.quantity               
                order_item.save()
                item.save()

            return JsonResponse({'MESSAGE': "SUCCESS"}, status=201)
        
        except KeyError:
            return JsonResponse({"MESSAGE": "KEY_ERROR"}, status=400)```
profile
baik9261@gmail.com

0개의 댓글