트랜잭션을 걸어줄려면 레포지토리 단계에서 작업을 해야된다고 한다.
그런데 우리조는 비즈니스로직 단계에서 이것저것 검증을 한 뒤 트랜잭션을 걸려고 서비스단계에서 작성을 했고, 역시나 실행을 해보면 트랜잭션이 작동을 안해서 오류가 났다.
한참을 고민하다 튜터님에게 질문을 드려보니 해답은 의외로 간단했다.
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;
}
};
// 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 });
};
}
이렇게 로직을 구성한 뒤 레포지토리에 트랜잭션도 같이 보내주면 해결되는 문제였다.