From 247547289823722ddb5e2e309ee8141a9f528211 Mon Sep 17 00:00:00 2001 From: TaeyeonKim Date: Sun, 23 Feb 2025 22:39:51 +0900 Subject: [PATCH] =?UTF-8?q?Refactor:=20#256=20transaction=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/chat/chat.repository.ts | 19 ++-------- src/modules/chat/chat.service.ts | 14 ++++---- src/modules/chatRoom/chatRoom.repository.ts | 33 +++++++++++------ src/modules/chatRoom/chatRoom.service.ts | 32 ++++++++++------- .../chatRoom/domain/chatRoom.domain.ts | 9 +++-- .../chatRoom/domain/chatRoom.interface.ts | 2 +- .../chatRoom/domain/chatRoom.properties.ts | 1 + src/modules/plan/plan.service.ts | 16 +++++++-- src/modules/quote/quote.repository.ts | 27 ++++++++++---- src/modules/quote/quote.service.ts | 36 ++++++++++++------- .../database/mongoose/config/mongo.config.ts | 2 +- .../transaction/transaction.manager.ts | 1 + 12 files changed, 119 insertions(+), 73 deletions(-) diff --git a/src/modules/chat/chat.repository.ts b/src/modules/chat/chat.repository.ts index 6e6ea63..b2d9cfe 100644 --- a/src/modules/chat/chat.repository.ts +++ b/src/modules/chat/chat.repository.ts @@ -12,10 +12,7 @@ import TransactionManager from 'src/providers/database/transaction/transaction.m @Injectable() export default class ChatRepository { - constructor( - @InjectModel(ChatRoom.name) private chatRoom: Model, - @InjectModel(Chat.name) private chat: Model - ) {} + constructor(@InjectModel(Chat.name) private chat: Model) {} async findChatsByChatRoomId(options: ChatQueryOptions): Promise { const { chatRoomId, page, pageSize } = options; @@ -44,7 +41,7 @@ export default class ChatRepository { const { senderId, chatRoomId, content, type } = data.toDB(); const session = TransactionManager.getMongoSession(); - const chat = await this.chat.create( + const [chat] = await this.chat.create( [ { senderId, @@ -56,17 +53,7 @@ export default class ChatRepository { { session } ); - const chatRoom = await this.chatRoom.updateOne( - { _id: chatRoomId }, - { $push: { chatIds: chat[0]._id } }, - { session } - ); - if (chatRoom.modifiedCount === 0) { - throw new InternalServerError(ErrorMessage.INTERNAL_SERVER_ERROR_CHAT_ROOM_UPDATE); - } - - const domainChat = new ChatMapper(chat[0]).toDomain(); - + const domainChat = new ChatMapper(chat).toDomain(); return domainChat; } diff --git a/src/modules/chat/chat.service.ts b/src/modules/chat/chat.service.ts index d4e6bcd..95f65a4 100644 --- a/src/modules/chat/chat.service.ts +++ b/src/modules/chat/chat.service.ts @@ -19,7 +19,7 @@ import Transactional from 'src/common/decorators/transaction.decorator'; @Injectable() export default class ChatService { constructor( - private readonly chatRepository: ChatRepository, + private readonly repository: ChatRepository, private readonly s3Service: S3Service, private readonly transactionManager: TransactionManager, @Inject(forwardRef(() => ChatRoomService)) private readonly chatRoomService: ChatRoomService @@ -29,8 +29,8 @@ export default class ChatService { options: ChatQueryOptions ): Promise<{ totalCount: number; list: ChatToClientProperties[] }> { const [totalCount, list] = await Promise.all([ - this.chatRepository.totalCount(options.chatRoomId), - this.chatRepository.findChatsByChatRoomId(options) + this.repository.totalCount(options.chatRoomId), + this.repository.findChatsByChatRoomId(options) ]); const toClientListPromise = list?.map((chat) => this.convertToClient(chat.toClient())); @@ -40,7 +40,7 @@ export default class ChatService { async getChatDomain(data: { id: string; userId?: string }) { const { id, userId } = data || {}; - const chat = await this.chatRepository.findChatById(id); + const chat = await this.repository.findChatById(id); if (!chat) { throw new NotFoundError(ErrorMessage.CHAT_NOT_FOUND_ERROR); @@ -66,7 +66,7 @@ export default class ChatService { async postChat(data: ChatCreateData): Promise { const chatData = Chat.create(data); - const chat = await this.chatRepository.createChat(chatData); + const chat = await this.repository.createChat(chatData); const convertChat = await this.convertToClient(chat.toClient()); return convertChat; @@ -76,7 +76,7 @@ export default class ChatService { const chatData = Chat.create(data); const s3key = await this.s3Service.uploadFile(chatData.toS3()); chatData.setS3Key(s3key); - const chat = await this.chatRepository.createChat(chatData); + const chat = await this.repository.createChat(chatData); const convertChat = await this.convertToClient(chat.toClient(), true); return convertChat; } @@ -98,7 +98,7 @@ export default class ChatService { const isActive = await this.chatRoomService.getIsActiveById(chatRoomId); if (!isActive) throw new BadRequestError(ErrorMessage.CHAT_ROOM_NOT_IS_ACTIVE); - await this.chatRepository.delete(id); + await this.repository.delete(id); } private handleDeletedMessage(chatData: ChatToClientProperties): ChatToClientProperties { diff --git a/src/modules/chatRoom/chatRoom.repository.ts b/src/modules/chatRoom/chatRoom.repository.ts index 675219d..54ee464 100644 --- a/src/modules/chatRoom/chatRoom.repository.ts +++ b/src/modules/chatRoom/chatRoom.repository.ts @@ -7,6 +7,7 @@ import { ChatQueryOptions } from 'src/modules/chat/types/chat.type'; import { FindChatRoomByIdOptions } from 'src/modules/chatRoom/types/chatRoom.type'; import { ChatRoom } from 'src/providers/database/mongoose/chatRoom.schema'; import { ObjectId } from 'mongodb'; +import TransactionManager from 'src/providers/database/transaction/transaction.manager'; @Injectable() export default class ChatRoomRepository { @@ -36,11 +37,13 @@ export default class ChatRoomRepository { async findChatRoom(options: FindChatRoomByIdOptions): Promise { const { chatRoomId, planId } = options || {}; + const session = TransactionManager.getMongoSession(); const chatRoom = await this.chatRoom .findOne({ $or: [{ _id: chatRoomId }, { planId }] }) + .session(session) .exec(); const domainChatRoom = new ChatRoomMapper(chatRoom).toDomain(); @@ -53,23 +56,33 @@ export default class ChatRoomRepository { } async createChatRoom(data: IChatRoom): Promise { + const session = TransactionManager.getMongoSession(); const { userIds, planId, planTitle, planTripDate, quotePrice } = data.toDB(); - const chatRoom = await this.chatRoom.create({ - planId, - planTitle, - planTripDate, - quotePrice, - userIds, - chatIds: [] - }); + const [chatRoom] = await this.chatRoom.create( + [ + { + planId, + planTitle, + planTripDate, + quotePrice, + userIds, + chatIds: [] + } + ], + { session } + ); const domainChatRoom = new ChatRoomMapper(chatRoom).toDomain(); return domainChatRoom; } async update(data: IChatRoom): Promise { - const { planId, isActive } = data.toDB(); - const chatRoom = await this.chatRoom.findOneAndUpdate({ planId }, { isActive }, { new: true }); + const session = TransactionManager.getMongoSession(); + const { planId, isActive, addChatId } = data.toDB(); + + const chatRoom = await this.chatRoom + .findOneAndUpdate({ planId }, { isActive, $addToSet: { chatIds: { $each: [addChatId] } } }, { new: true }) + .session(session); const domainChatRoom = new ChatRoomMapper(chatRoom).toDomain(); return domainChatRoom; } diff --git a/src/modules/chatRoom/chatRoom.service.ts b/src/modules/chatRoom/chatRoom.service.ts index a2de95b..ff3c4b2 100644 --- a/src/modules/chatRoom/chatRoom.service.ts +++ b/src/modules/chatRoom/chatRoom.service.ts @@ -13,15 +13,17 @@ import { ChatReference, FileUploadData, FindChatRoomByIdOptions } from 'src/modu import NotFoundError from 'src/common/errors/notFoundError'; import IChatRoom from './domain/chatRoom.interface'; import BadRequestError from 'src/common/errors/badRequestError'; +import TransactionManager from 'src/providers/database/transaction/transaction.manager'; import Transactional from 'src/common/decorators/transaction.decorator'; @Injectable() export default class ChatRoomService { private readonly connectedClients = new Map(); constructor( - private readonly chatRoomRepository: ChatRoomRepository, + private readonly repository: ChatRoomRepository, private readonly chatService: ChatService, - private readonly userService: UserService + private readonly userService: UserService, + private readonly transactionManager: TransactionManager ) {} registerClient(userId: string, client: Socket) { @@ -44,21 +46,21 @@ export default class ChatRoomService { } async getChatRooms(options: ChatQueryOptions): Promise<{ totalCount: number; list: ChatRoomWithUserInfo[] }> { - const totalCount = await this.chatRoomRepository.totalCount(options.userId); - const list = await this.chatRoomRepository.findManyChatRooms(options); + const totalCount = await this.repository.totalCount(options.userId); + const list = await this.repository.findManyChatRooms(options); const toClientList = await Promise.all(list?.map((chatRoom) => this.fetchAndFormatUserInfo(chatRoom.toClient()))); return { list: toClientList, totalCount }; } async getActiveChatRoomIds(userId: string): Promise { - const chatRoomIds = await this.chatRoomRepository.findActiveChatRoomIdsByUserId(userId); + const chatRoomIds = await this.repository.findActiveChatRoomIdsByUserId(userId); return chatRoomIds; } async getChatRoomDomain(options: FindChatRoomByIdOptions): Promise { const { userId } = options || {}; - const chatRoom = await this.chatRoomRepository.findChatRoom(options); + const chatRoom = await this.repository.findChatRoom(options); if (!chatRoom) { throw new NotFoundError(ErrorMessage.CHAT_ROOM_NOTFOUND); @@ -91,13 +93,15 @@ export default class ChatRoomService { return { totalCount, list }; } + @Transactional() async postChatRoom(data: ChatRoomProperties): Promise { const chatRoomData = ChatRoom.create(data); - const isChatRoom = await this.chatRoomRepository.findChatRoom({ planId: data.planId }); - if (!isChatRoom) await this.chatRoomRepository.createChatRoom(chatRoomData); + const isChatRoom = await this.repository.findChatRoom({ planId: data.planId }); + if (!isChatRoom) await this.repository.createChatRoom(chatRoomData); //NOTE. 로직상 채팅방이 이미 있으면 안되지만 개발상의 편의를 위해 추가 } + @Transactional() async postChat(data: ChatCreateData): Promise { const { senderId, chatRoomId } = data; @@ -106,6 +110,8 @@ export default class ChatRoomService { if (chatRoom.getIsActive() === false) throw new BadRequestError(ErrorMessage.CHAT_ROOM_NOT_IS_ACTIVE); const chatData = await this.chatService.postChat(data); + chatRoom.update({ chatId: chatData.id }); + await this.repository.update(chatRoom); await this.sendMessageToChatRoom(chatData); return chatData; @@ -121,17 +127,17 @@ export default class ChatRoomService { return chatData; } + @Transactional() async deActive(planId: string): Promise { - const chatRoom = await this.chatRoomRepository.findChatRoom({ planId }); - //NOTE. 일단 임시로 트랜젝션을 제외 + const chatRoom = await this.repository.findChatRoom({ planId }); if (chatRoom) { - chatRoom.update(); - await this.chatRoomRepository.update(chatRoom); + chatRoom.update({ deActive: true }); + await this.repository.update(chatRoom); } //NOTE. 채팅방 목데이터가 없어서 나는 에러 처리 } async deActiveMany(planIds: string[]): Promise { - await this.chatRoomRepository.updateMany(planIds); + await this.repository.updateMany(planIds); } async sendMessageToChatRoom(chat: ChatReference) { diff --git a/src/modules/chatRoom/domain/chatRoom.domain.ts b/src/modules/chatRoom/domain/chatRoom.domain.ts index b1429d3..dcac30e 100644 --- a/src/modules/chatRoom/domain/chatRoom.domain.ts +++ b/src/modules/chatRoom/domain/chatRoom.domain.ts @@ -15,6 +15,7 @@ export default class ChatRoom implements IChatRoom { private chatIds: string[]; private lastChat: string; private isActive?: boolean; + private addChatId: string; constructor(private chatRoom: ChatRoomProperties) { this.id = chatRoom.id; @@ -41,7 +42,8 @@ export default class ChatRoom implements IChatRoom { planTitle: this.planTitle, planTripDate: this.planTripDate, quotePrice: this.quotePrice, - isActive: this.isActive + isActive: this.isActive, + addChatId: this.addChatId }; } @@ -60,8 +62,9 @@ export default class ChatRoom implements IChatRoom { }; } - update(): void { - this.isActive = false; + update(data: { deActive: boolean; chatId: string }): void { + if (data.deActive) this.isActive = false; + if (data.chatId) this.addChatId = data.chatId; } getId(): string { diff --git a/src/modules/chatRoom/domain/chatRoom.interface.ts b/src/modules/chatRoom/domain/chatRoom.interface.ts index 8f8a5b9..0af8512 100644 --- a/src/modules/chatRoom/domain/chatRoom.interface.ts +++ b/src/modules/chatRoom/domain/chatRoom.interface.ts @@ -3,7 +3,7 @@ import { ChatRoomProperties } from './chatRoom.properties'; export default interface IChatRoom { toDB(): ChatRoomProperties; toClient(): ChatRoomProperties; - update(): void; + update(data: { deActive?: boolean; chatId?: string }): void; getId(): string; getUserIds(): string[]; getIsActive(): boolean; diff --git a/src/modules/chatRoom/domain/chatRoom.properties.ts b/src/modules/chatRoom/domain/chatRoom.properties.ts index e25f489..bab597e 100644 --- a/src/modules/chatRoom/domain/chatRoom.properties.ts +++ b/src/modules/chatRoom/domain/chatRoom.properties.ts @@ -13,6 +13,7 @@ export interface ChatRoomProperties { chatIds?: string[] | { content: string; type: ChatType }; lastChat?: string; isActive?: boolean; + addChatId?: string; } export interface ChatRoomWithUserInfo { diff --git a/src/modules/plan/plan.service.ts b/src/modules/plan/plan.service.ts index 3df2ebf..7b419f3 100644 --- a/src/modules/plan/plan.service.ts +++ b/src/modules/plan/plan.service.ts @@ -144,6 +144,7 @@ export default class PlanService { return plan.toClientWithAddress(); } + @Transactional() async postQuote(data: CreateOptionalQuoteData, userId: string, planId: string): Promise { const plan = await this.repository.findById(planId); @@ -164,6 +165,7 @@ export default class PlanService { return quote; } + @Transactional() async requestPlanAssign(data: AssignData): Promise { const { id, userId, assigneeId } = data; const plan = await this.repository.findById(data.id); @@ -199,6 +201,7 @@ export default class PlanService { return updatedPlan.toClient(); } + @Transactional() async rejectPlanAssign(data: AssignData): Promise { const plan = await this.repository.findById(data.id); @@ -210,11 +213,18 @@ export default class PlanService { const updatedPlan = await this.repository.update(plan); const makerNickName = plan.getAssigneeNickName(data.assigneeId); + const dreamerNickName = plan.getDreamerNickName(); + const dreamerId = plan.getDreamerId(); const planTitle = plan.getTitle(); + // this.eventEmitter.emit('notification', { + // userId: data.assigneeId, + // event: NotificationEventName.REJECT_REQUEST, + // payload: { nickName: makerNickName, planTitle } + // }); this.eventEmitter.emit('notification', { - userId: data.assigneeId, + userId: dreamerId, event: NotificationEventName.REJECT_REQUEST, - payload: { nickName: makerNickName, planTitle } + payload: { nickName: dreamerNickName, planTitle } }); return updatedPlan.toClient(); @@ -299,7 +309,9 @@ export default class PlanService { if (plan.getStatus() === StatusValues.CONFIRMED) { throw new BadRequestError(ErrorMessage.PLAN_DELETE_BAD_REQUEST); } + const quotes = plan.getQuoteIds(); + await this.quoteService.deleteManyQuotes(id); const deletedPlan = await this.repository.delete(id); const dreamerNickName = deletedPlan.getDreamerNickName(); diff --git a/src/modules/quote/quote.repository.ts b/src/modules/quote/quote.repository.ts index a0947e7..580b5e2 100644 --- a/src/modules/quote/quote.repository.ts +++ b/src/modules/quote/quote.repository.ts @@ -5,11 +5,16 @@ import { QuoteIncludeConditions, QuoteQueryOptions, QuoteWhereConditions } from import IQuote from './domain/quote.interface'; import QuoteMapper from './domain/quote.mapper'; import { StatusValues } from 'src/common/constants/status.type'; +import TransactionManager from 'src/providers/database/transaction/transaction.manager'; @Injectable() export default class QuoteRepository { constructor(private readonly db: DBClient) {} + private getPrismaClient() { + return TransactionManager.getPrismaClient() || this.db; + } + async findMany(options: QuoteQueryOptions): Promise { const { page, pageSize, isSent } = options; const whereConditions = this.buildWhereConditions(options); @@ -18,7 +23,7 @@ export default class QuoteRepository { isSent === true ? [{ plan: { status: SortOrder.ASC } }, { createdAt: SortOrder.DESC }] : { createdAt: SortOrder.DESC }; - const quotes = await this.db.quote.findMany({ + const quotes = await this.getPrismaClient().quote.findMany({ where: whereConditions, take: pageSize, skip: (page - 1) * pageSize, @@ -32,7 +37,7 @@ export default class QuoteRepository { async totalCount(options: QuoteQueryOptions): Promise { const whereConditions = this.buildWhereConditions(options); - const totalCount = await this.db.quote.count({ + const totalCount = await this.getPrismaClient().quote.count({ where: whereConditions }); return totalCount; @@ -41,7 +46,7 @@ export default class QuoteRepository { async findById(id: string): Promise { const includeConditions = this.buildIncludeConditions(); - const quote = await this.db.quote.findUnique({ + const quote = await this.getPrismaClient().quote.findUnique({ where: { id, isDeletedAt: null }, include: includeConditions }); @@ -52,7 +57,7 @@ export default class QuoteRepository { async exists(options: { planId: string; userId: string }): Promise { const whereConditions = this.buildWhereConditions(options); - const quote = await this.db.quote.findFirst({ + const quote = await this.getPrismaClient().quote.findFirst({ where: whereConditions }); return quote !== null; @@ -60,7 +65,7 @@ export default class QuoteRepository { async create(data: IQuote): Promise { const { planId, makerId, isAssigned, price, content } = data.toDB(); - const quote = await this.db.quote.create({ + const quote = await this.getPrismaClient().quote.create({ data: { plan: { connect: { id: planId } }, maker: { connect: { id: makerId } }, @@ -81,7 +86,7 @@ export default class QuoteRepository { async update(data: IQuote): Promise { const { id, isConfirmed } = data.toDBForUpdate(); - const quote = await this.db.quote.update({ + const quote = await this.getPrismaClient().quote.update({ where: { id }, data: { isConfirmed, @@ -105,7 +110,7 @@ export default class QuoteRepository { } async delete(id: string): Promise { - const quote = await this.db.quote.update({ + const quote = await this.getPrismaClient().quote.update({ where: { id }, data: { isDeletedAt: new Date() } }); @@ -115,6 +120,14 @@ export default class QuoteRepository { return domainQuote.toDomain(); } + async deleteMany(planId: string): Promise<{ count: number }> { + const deleteCount = await this.getPrismaClient().quote.updateMany({ + where: { planId, isDeletedAt: null }, + data: { isDeletedAt: new Date() } + }); + return deleteCount; + } + private buildWhereConditions(options: Partial): QuoteWhereConditions { const { planId, isConfirmed, isSent, userId } = options || {}; let whereConditions: QuoteWhereConditions = { diff --git a/src/modules/quote/quote.service.ts b/src/modules/quote/quote.service.ts index 761c7ec..3a15ed0 100644 --- a/src/modules/quote/quote.service.ts +++ b/src/modules/quote/quote.service.ts @@ -16,22 +16,25 @@ import ChatRoomService from '../chatRoom/chatRoom.service'; import { InjectQueue } from '@nestjs/bullmq'; import { Queue } from 'bullmq'; import { PointEventEnum } from 'src/common/constants/pointEvent.type'; +import Transactional from 'src/common/decorators/transaction.decorator'; +import TransactionManager from 'src/providers/database/transaction/transaction.manager'; @Injectable() export default class QuoteService { constructor( @InjectQueue('points') private readonly pointQueue: Queue, - private readonly quoteRepository: QuoteRepository, + private readonly repository: QuoteRepository, private readonly userService: UserService, - private readonly chatRoomService: ChatRoomService + private readonly chatRoomService: ChatRoomService, + private readonly transactionManager: TransactionManager ) {} async getQuotesByPlanId( options: QuoteQueryOptions ): Promise<{ totalCount: number; list: QuoteToClientProperties[] }> { const [totalCount, list] = await Promise.all([ - this.quoteRepository.totalCount(options), - this.quoteRepository.findMany(options) + this.repository.totalCount(options), + this.repository.findMany(options) ]); const toClientList = await Promise.all(list.map(async (quote) => await this.mapToMakerProfile(quote, false))); @@ -41,8 +44,8 @@ export default class QuoteService { async getQuotesByMaker(options: QuoteQueryOptions): Promise<{ totalCount: number; list: QuoteToClientProperties[] }> { const [list, totalCount] = await Promise.all([ - this.quoteRepository.findMany(options), - this.quoteRepository.totalCount(options) + this.repository.findMany(options), + this.repository.totalCount(options) ]); const toClientList = list.map((quote) => quote.toMaker()); @@ -51,7 +54,7 @@ export default class QuoteService { } async getQuoteById(id: string, userId: string, role: Role): Promise { - const quote = await this.quoteRepository.findById(id); + const quote = await this.repository.findById(id); if (!quote) throw new NotFoundError(ErrorMessage.QUOTE_NOT_FOUND); @@ -64,20 +67,22 @@ export default class QuoteService { return this.mapToMakerProfile(quote, true); } + @Transactional() async createQuote(data: QuoteProperties): Promise { const planId = data.planId; const makerId = data.makerId; - const isQuote = await this.quoteRepository.exists({ planId, userId: makerId }); + const isQuote = await this.repository.exists({ planId, userId: makerId }); if (isQuote) throw new ConflictError(ErrorMessage.QUOTE_CONFLICT); const quoteData = Quote.create(data); - const quote = await this.quoteRepository.create(quoteData); + const quote = await this.repository.create(quoteData); return quote.toClient(); } + @Transactional() async update(id: string, userId: string, data: { isConfirmed: boolean }): Promise { - const quote = await this.quoteRepository.findById(id); + const quote = await this.repository.findById(id); if (!quote) throw new NotFoundError(ErrorMessage.QUOTE_NOT_FOUND); if (userId !== quote.getDreamerId()) { @@ -94,7 +99,7 @@ export default class QuoteService { throw new BadRequestError(ErrorMessage.QUOTE_BAD_REQUEST_UPDATE_NOT_PENDING); } - const updatedQuote = await this.quoteRepository.update(quote.update(data)); + const updatedQuote = await this.repository.update(quote.update(data)); await this.chatRoomService.postChatRoom(updatedQuote.toChatRoom()); @@ -107,8 +112,9 @@ export default class QuoteService { return updatedQuote.toClient(); } + @Transactional() async deleteQuote(id: string, userId: string): Promise { - const quote = await this.quoteRepository.findById(id); + const quote = await this.repository.findById(id); if (!quote) throw new NotFoundError(ErrorMessage.QUOTE_NOT_FOUND); if (userId !== quote.getMakerId()) throw new ForbiddenError(ErrorMessage.QUOTE_FORBIDDEN_MAKER); @@ -117,7 +123,11 @@ export default class QuoteService { throw new BadRequestError(ErrorMessage.QUOTE_DELETE_BAD_REQUEST_STATUS); } - await this.quoteRepository.delete(id); + await this.repository.delete(id); + } + + async deleteManyQuotes(planId: string): Promise { + await this.repository.deleteMany(planId); } private async mapToMakerProfile(quote: IQuote, isPlan: boolean): Promise { diff --git a/src/providers/database/mongoose/config/mongo.config.ts b/src/providers/database/mongoose/config/mongo.config.ts index 244ccc0..7b00846 100644 --- a/src/providers/database/mongoose/config/mongo.config.ts +++ b/src/providers/database/mongoose/config/mongo.config.ts @@ -5,7 +5,7 @@ export default async function getMongoConfig() { user: process.env.MONGO_USER, pass: process.env.MONGO_PASS, authSource: process.env.MONGO_AUTH_SOURCE, - retryWrites: true, // 트랜잭션이 실패한 경우 자동으로 재시도 + retryWrites: true, useNewUrlParser: true, // 새로운 URL 파서 사용 useUnifiedTopology: true // MongoDB 드라이버의 새로운 연결 방식 사용 }; diff --git a/src/providers/database/transaction/transaction.manager.ts b/src/providers/database/transaction/transaction.manager.ts index 8aeb5e9..ef0cad5 100644 --- a/src/providers/database/transaction/transaction.manager.ts +++ b/src/providers/database/transaction/transaction.manager.ts @@ -26,6 +26,7 @@ export default class TransactionManager { asyncLocalStorage.getStore().set('prisma', prisma); const callbackResult = await callback(); await session.commitTransaction(); + return callbackResult; });