[TIL] 3계층구조 트랜잭션 23.07.25

이상훈·2023년 7월 26일
0

[내일배움캠프]

목록 보기
49/68

트랜잭션을 걸어줄려면 레포지토리 단계에서 작업을 해야된다고 한다.
그런데 우리조는 비즈니스로직 단계에서 이것저것 검증을 한 뒤 트랜잭션을 걸려고 서비스단계에서 작성을 했고, 역시나 실행을 해보면 트랜잭션이 작동을 안해서 오류가 났다.
한참을 고민하다 튜터님에게 질문을 드려보니 해답은 의외로 간단했다.

service.js 코드

isDelivered = async (orderId, res) => {
    try {
      const user = res.locals.user;
      const existStore = await this.storeRepository.getStoreInfo(user.id);
      if (!existStore) throw errorHandler.notRegistered;

      const order = await this.orderRepository.findOrder(orderId);
      if (!order) throw errorHandler.noOrder;

      if (order.order_status === 'delivered') throw errorHandler.completedOrder;
      else if (order.order_status === 'refundRequest') throw errorHandler.refundOrder;
      else if (order.order_status === 'cancelled') throw errorHandler.cancelledOrder;

      const total_sales = existStore.total_sales + order.total_price;
      const t = await sequelize.transaction({
        isolationLevel: Transaction.ISOLATION_LEVELS.READ_COMMITTED,
      });
      try {
        await this.orderRepository.updateDeliveryStatus(orderId, t);
        await this.storeRepository.updateStoreInSales(user.id, total_sales, t);
        await t.commit();
        return {
          code: 201,
          message: `배달이 완료되었습니다. ${order.total_price}포인트가 입금 되었습니다.`,
          data: { userId: order.user_id },
        };
      } catch (transactionError) {
        await t.rollback();
        throw transactionError;
      }
    } catch (err) {
      throw err;
    }
  };

repository.js

// order
  updateDeliveryStatus = async (orderId, t) => {
    await Order.update({ order_status: 'delivered' }, { where: { id: orderId }, transaction: t });
    return;
  };
// store
  updateStoreInSales = async (userId, price, t) => {
    await Store.update({ total_sales: price }, { where: { user_id: userId }, transaction: t });
  };
}

이렇게 로직을 구성한 뒤 레포지토리에 트랜잭션도 같이 보내주면 해결되는 문제였다.

profile
코린이

0개의 댓글