편리한 트랜잭션 API 사용
이 페이지의 내용
트랜잭션을 수행하여 전체 트랜잭션이 커밋될 때까지 데이터를 변경하지 않는 일련의 작업을 실행할 수 있습니다. 이 사용 예제에서는 편리한 트랜잭션 API 를 사용하여 트랜잭션을 수행합니다.
팁
다음도 참조하세요.
예시
고객이 상점에서 품목을 구매하는 상황을 가정해 보겠습니다. 구매를 기록하려면 애플리케이션에서 재고를 업데이트하고 주문 정보를 기록해야 합니다.
다음 표에서는 구매 데이터를 저장하는 collection과 구매가 각 collection의 데이터를 변경하는 방법에 대해 설명합니다.
컬렉션 | 작업 | 변경 사항 설명 |
---|---|---|
| insert | 주문을 설명하는 문서를 삽입합니다 |
| update | 구매 후 사용 가능한 품목의 수량 업데이트 |
샘플 데이터
inventory
컬렉션에는 다음 문서가 포함되어 있습니다.
{ item: "sunblock", qty: 85, price: 6.0 }, { item: "beach chair", qty: 30, price: 25.0 }
데이터베이스의 collection 컬렉션에 구매 기록을 저장합니다.orders
testdb
이 collection은 구매가 없으므로 비어 있습니다.
구현
이 섹션의 코드 예제에서는 편리한 트랜잭션 API를 사용하여 세션에서 다중 문서 트랜잭션을 수행하는 방법을 보여줍니다. 이 예제에서는 트랜잭션이 고객이 매장에서 품목을 구매할 때 필요한 변경을 수행합니다.
이 예시 코드는 다음 조치를 통해 트랜잭션을 수행합니다.
클라이언트에서
withSession()
메서드를 호출하여 암시적으로 세션을 만들고 세션 내에서 전달된 콜백을 실행합니다.세션에서
withTransaction()
메서드를 호출하여 트랜잭션을 만들고, 전달된 콜백을 실행하고, 트랜잭션을 커밋합니다. 트랜잭션이 실패하면 이 메서드는 트랜잭션을 종료하고 오류 메시지를 반환합니다.트랜잭션 내에서 다음 작업을 수행합니다.
구매를 처리하기에 충분한 재고가 있는 경우
inventory
및orders
collection을 업데이트합니다.주문에 포함된 품목에 대한 재고가 충분하지 않은 경우 트랜잭션을 종료하고 예외를 발생시킵니다.
구매 기록의 사본을 사용하여 트랜잭션이 성공적으로 커밋되었음을 확인하는 메시지를 반환합니다.
오류 메시지 또는 트랜잭션이 완료되었다는 승인인
withSession()
의 반환 유형을 인쇄합니다.
const txnResult = await client.withSession(async (session) => session .withTransaction(async (session) => { const invColl = client.db("testdb").collection("inventory"); const recColl = client.db("testdb").collection("orders"); let total = 0; for (const item of order) { /* Update the inventory for the purchased items. End the transaction if the quantity of an item in the inventory is insufficient to complete the purchase. */ const inStock = await invColl.findOneAndUpdate( { item: item.item, qty: { $gte: item.qty }, }, { $inc: { qty: -item.qty } }, { session } ); if (inStock === null) { await session.abortTransaction(); return "Item not found or insufficient quantity."; } const subTotal = item.qty * inStock.price; total = total + subTotal; } // Create a record of the purchase const receipt = { date: new Date(), items: order, total: total, }; await recColl.insertOne(receipt, { session }); return ( "Order successfully completed and recorded!\nReceipt:\n" + JSON.stringify(receipt, null, 1) ); }, null) .finally(async () => await client.close()) ); console.log(txnResult);
샘플 주문 및 트랜잭션 결과
이 섹션에서는 두 개의 샘플 주문에 대해 수행된 트랜잭션의 결과를 설명합니다.
다음 주문에 대한 충분한 재고가 있으므로 트랜잭션이 성공적으로 완료됩니다.
{ item: "sunblock", qty: 3 }, { item: "beach chair", qty: 1 }
이 주문을 예제 트랜잭션 코드에 전달하면 코드는 다음 결과를 출력합니다.
Order successfully completed and recorded! Receipt: { "date": "2023-08-25T20:06:52.564Z", "items": [ { "item": "sunblock", "qty": 3 }, { "item": "beach chair", "qty": 1 } ], "total": 43, "_id": "..." }
inventory
컬렉션에서 "sunblock"
의 수량은 이제 82
이고 "beach chair"
의 수량은 29
입니다. orders
collection에는 구매 기록이 포함되어 있습니다.
다음 주문에 대한 재고가 충분하지 않으므로 드라이버는 트랜잭션을 종료합니다.
{ item: "volleyball", qty: 1 }
이 주문을 예제 트랜잭션 코드에 전달하면 코드는 다음 결과를 출력합니다.
Item not found or insufficient quantity.
드라이버가 트랜잭션을 종료하므로 inventory
및 orders
collection은 변경되지 않습니다.
API 문서
이 사용 예제에서 설명한 메서드 또는 유형에 대해 자세히 알아보려면 다음 API 설명서를 참조하세요.