개인 과제 회고) mysql2 라이브러리
import pools from '../pools.js';
import USER_SQL_QUERIES from './user.queries.js';
const insertUserData = async (id, password, email) => {
const connection = await pools.USER_DB.getConnection();
await connection.beginTransaction();
await connection.execute(USER_SQL_QUERIES.INSERT_USER, [id, password, email]);
await connection.execute(USER_SQL_QUERIES.INSERT_DEFAULT_RANK, [id]);
await connection.commit();
};
테이블 두 개로 인한 트랜잭션 시도... 순수 mysql 쿼리라면 어찌저찌 했을 텐데, node.js의 mysql2 라이브러리를 사용해야하는지라, 관련 프로퍼티나 메서드를 공부해야할 필요가 생겼다!! 참 험난한 길이었고... 저 코드 결과물을 얻어낼 수 있었다!! 그래서 오늘은 저 기초적인 코드를 단계적으로 복기해보면서, 정리할 예정!! 우선 pools는 pool들을 매핑할 수 있도록 마련해둔 객체고, 지금은 USER_DB를 매핑하고 있다!! 그래서 pool은 무엇인고 하면!!
const pool = mysql.createPool({
host: db1Host,
port: db1Port,
user: db1User,
password: db1Password,
database: db1Name,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 10,
});
첫번째 메서드인 createPool()이다!! 데이터베이스 서버와 연결할 때 사용되는 "커넥션 풀"을 위한 메서드인디, 자주 나오는 다른 "풀"들과 마찬가지로, 미리 몇 가지의 연결을 맺어놓고, 데이터베이스에 접근이 필요할 때마다 그 연결들을 꺼내쓰는 것을 말한다!! 매 쿼리마다 데이터베이스 서버와 새로 연결을 맺고, 해제하고 하면 오래 걸리기도 하고, 불필요한 부하도 쌓이니까는, 활용하는 유용한 방식!! 아무튼 이 방식으로 pool을 미리 만들어 놓았다!!
const connection = await pools.USER_DB.getConnection();
다음으로 볼 것은 바로 getConnection() 메서드다!! 이 넘은 이름 그대로, 커넥션을 하나 가져오는 역할을 한다!! 우리가 만들어놓은 pool에서 연결을 하나 가져와서, 변수에 할당해놓는다!! 연결이 돼야 쿼리를 보내니까!!
await connection.beginTransaction();
await connection.execute(USER_SQL_QUERIES.INSERT_USER, [id, password, email]);
await connection.execute(USER_SQL_QUERIES.INSERT_DEFAULT_RANK, [id]);
await connection.commit();
여기는 한꺼번에!! 원래는 쿼리 문에서 트랜잭션을 활용하고 싶었으나, 세미콜론을 올바르게 인식하지 못 하는 것인지, 의도대로 실행되지 않았다...! 때문에 쿼리문을 둘 해놓고, 코드 상에서 트랜잭션을 하게 됐고, 이를 위해 mysql2 라이브러리의 메서드들을 활용하게 됐다!! 아주 간단한디, beginTransaction()으로 트랜잭션 시작을 알리고, commit()으로 트랜잭션 종료를 알린다!! 그리고 둘 사이에 실행된 쿼리는 모두 트랜잭션에 묶이고, 혹시 어느 한 쿼리에라도 문제가 생긴다면, 바로 자동 rollback이 되는 것!! 그렇게 원하는대로 두 테이블에 한 번에 데이터를 넣을 수 있게 되었다!! 아래는 최종 형태!!
const insertUserData = async (id, password, email) => {
// [1] 커넥션 풀에서 연결 하나 꺼내오기
const connection = await pools.USER_DB.getConnection();
// [2] 트랜잭션 트라이하기 (users 테이블과 ranks 테이블에 데이터 같이 넣기 위함)
try {
await connection.beginTransaction();
await connection.execute(USER_SQL_QUERIES.INSERT_USER, [id, password, email]);
await connection.execute(USER_SQL_QUERIES.INSERT_DEFAULT_RANK, [id]);
// [3 A] 트랜잭션이 무사히 끝나면 쿼리 완료 알리기
await connection.commit();
} catch (error) {
// [3 B] 트랜잭션 실패 시 롤백하고, 에러 객체 상위 함수로 전달
await connection.rollback();
throw error;
} finally {
// [4] 아무튼 쿼리가 종료됐으면 사용한 연결을 풀에 돌려주기
connection.release();
}
};
참고) pool에 바로 query() 하는 것과 getConnection() 이후에 query()하는 것의 차이
pool.query() | pool.getConnection().query() | |
풀에서 커넥션 꺼내기 | 자동으로 하나 꺼내서 쿼리 실행 후, 다 쓰면 자동으로 반환 | 수동으로 꺼냈기 때문에 쿼리 마치면 release()를 꼭 해주어야함 |
트랜잭션 지원 여부 | 지원 X,한 번에 하나의 쿼리만 가능하기 때문 | 지원 O, 한 번 가져온 커넥션에 여러 쿼리 가능 |
호출 속도 | 조금 더 빠를 수 이씀 | 커넥션을 수동으로 꺼내는 과정이 있으니 당연하게도 약간의 오버헤드가 추가될 수 이씀 |
'TIL&WIL' 카테고리의 다른 글
250204 TIL - protoc 실습해보기 (0) | 2025.02.05 |
---|---|
250203 TIL - 심야 만담회의 순기능 (1) | 2025.02.04 |
250122 TIL - ECS Architecture (0) | 2025.01.22 |
250120 TIL - 소수 관련 알고리즘 팁 (0) | 2025.01.20 |
250117 TIL - 알고리즘 풀이 회고 (0) | 2025.01.17 |