공통점
| 항목 | createConnection() | createPool() |
| DB 연결 객체 | conn | conn (getConnection으로 가져옴) |
| 트랜잭션 사용 | 가능 (beginTransaction, commit, rollback) | 가능 (동일하게 사용) |
| 쿼리 실행 | conn.query(...) | conn.query(...) |
→ 둘 다 트랜잭션을 지원하며 쿼리 방식도 동일합니다
차이점
| 항목 | createConnection() | createPool() |
| 연결 개수 | 1개만 생성 | 여러 개 (기본은 connectionLimit으로 설정) |
| 재사용성 | 없음 (직접 관리) | 있음 (풀에서 꺼내 쓰고 반환) |
| 병렬 처리 | 불안정 (모든 요청이 하나의 conn 공유) | 안전 (요청마다 독립 conn 제공) |
| 성능 | 낮음 (연결 매번 생성하거나 공유) | 높음 (풀에서 빠르게 할당) |
| 실무 적합성 | 테스트용 또는 단일 사용자 환경 | 실무 권장 방식 |
실제로 많이 쓰는 구조
| 상황 | 권장 방식 |
| 학습, 테스트, 스크립트 | createConnection() |
| 웹 서비스, API 서버 | createPool() + getConnection() + release() |
한 줄 요약
createConnection()과 createPool()은 둘 다 트랜잭션을 지원하지만,
하나는 연결 하나, 하나는 연결 여러 개 관리한다는 점에서 구조적 차이가 있다.
실무에선 안전성과 확장성 때문에 **풀(pool)**을 반드시 사용한다.
실제 예시 코드 (도서구매사이트 : 주문하기 API)
// 주문 하기
async function postOrder(req, res) {
const { user_id, cart_id_arr, adress, receiver } = req.body;
// 1. DB 연결 객체 가져오기 (mysql2/promise의 pool에서 connection 하나 가져옴)
const conn = await pool.getConnection();
let totalPrice = 0;
try {
// 2. 트랜잭션 시작 (이 시점부터 수동으로 커밋하기 전까지는 쿼리 결과가 확정되지 않음)
await conn.beginTransaction();
// 3. 장바구니(cart) 테이블에서 주문할 도서 목록을 한 번에 조회 (도서 가격 포함)
const [order_items] = await conn.query(
`SELECT cart.book_id, cart.count, books.price
FROM cart
JOIN books ON cart.book_id = books.id
WHERE cart.id IN (?)`,
[cart_id_arr]
);
// 4. orders 테이블에 주문 정보 먼저 저장 (총 금액은 아직 0으로 넣어둠)
const [result_order_insert] = await conn.query(
`INSERT INTO orders (user_id, adress, receiver, totalPrice)
VALUES (?, ?, ?, ?)`,
[user_id, adress, receiver, 0]
);
const order_id = result_order_insert.insertId; // 방금 생성된 주문의 고유 ID
// 5. orderItems 테이블에 주문 상세 정보 저장 + 총 금액 계산
for (const item of order_items) {
// 각 주문 항목 저장
await conn.query(
`INSERT INTO orderItems (book_id, count, order_id) VALUES (?, ?, ?)`,
[item.book_id, item.count, order_id]
);
// 금액 누적 계산
totalPrice += item.price * item.count;
}
// 6. orders 테이블에 총 금액(totalPrice) 업데이트
await conn.query(
`UPDATE orders SET totalPrice = ? WHERE id = ?`,
[totalPrice, order_id]
);
// 7. 주문이 완료되었으므로 장바구니에서 해당 항목들 삭제
await conn.query(
`DELETE FROM cart WHERE id IN (?)`,
[cart_id_arr]
);
// 8. 지금까지의 모든 쿼리 실행을 최종적으로 확정(commit)
await conn.commit();
// 9. 클라이언트에 성공 응답
res.status(StatusCodes.OK).end();
}
catch (err) {
// 10. 중간에 어떤 에러가 발생했다면 지금까지의 모든 작업을 취소 (rollback)
await conn.rollback();
console.error("에러 : ", err);
res.status(StatusCodes.BAD_REQUEST).json({ message: "주문하기 실패" });
}
finally {
// 11. try든 catch든 상관없이 DB 연결은 반드시 반환해야 다음 요청에서 재사용 가능
conn.release();
}
}'mariaDB > 3. SQL 사용법' 카테고리의 다른 글
| 도서구매사이트 - 주문목록 조회 (0) | 2025.05.24 |
|---|---|
| 방금 테이블에 INSERT한 row의 ID를 가져오기 (0) | 2025.05.21 |
| 도서구매사이트 - 주문 API 작성 시 코드 리팩토링 (0) | 2025.05.21 |
| IN (?, ?, ?) 문법 (0) | 2025.05.20 |
| EXISTS 문법 (0) | 2025.05.19 |