728x90
맥북에 mysql 5.7 설치 후 진행했습니다.
connection pool 생성 후 트랜잭션을 이용해 정상 처리시 commit을 에러시 rollback을..
커넥션풀 생성
const mysql = require('mysql2/promise');
const {
MYSQL_HOST,
MYSQL_USER,
MYSQL_PW,
MYSQL_DB,
} = process.env;
module.exports = mysql.createPool({
host: MYSQL_HOST,
user: MYSQL_USER,
password: MYSQL_PW,
database: MYSQL_DB,
connectTimeout: 5000,
connectionLimit: 30 //default 10
})
먼저 데이터 insert
router.post('/insert', async (req, res) => {
let rt = {
ok : false,
msg : '',
result : null
}
const params = req.body;
let conn = null;
try {
if (params.user_id === undefined || params.user_id === '') throw { message : '아이디 없음'};
if (params.user_nm === undefined || params.user_nm === '') throw { message : '이름 없음'};
if (params.user_pw === undefined || params.user_pw === '') throw { message : '패스워드 없음'};
const sql = `INSERT INTO ${table} (user_id, user_nm, user_pw, user_addr, user_mk_dt, user_upd_dt, is_use) VALUES (
"${params.user_id}",
"${params.user_nm}",
"${encryptPassword(params.user_pw)}",
"${params.user_addr}",
NOW(),
NOW(),
1
)`;
conn = await mysql.getConnection();
//트랜잭션 시작
await conn.beginTransaction();
const [ rows ] = await conn.query(sql);
rt.ok = true;
rt.msg = 'ok';
rt.result = rows;
await conn.commit(); //commit
conn.release();
} catch (err) {
console.error('userTable/insert Error!!', err);
rt.msg = 'user_insert Error';
rt.result = err.message;
if (conn !== null) {
await conn.rollback(); //rollback
conn.release();
}
}
res.send(rt);
})
데이터 update
router.post('/update', async (req, res) => {
let rt = {
ok: false,
msg: '',
result: null
}
const params = req.body;
let conn = null;
try {
let sql = `UPDATE ${table} SET `;
//---------------
let tmp = [];
if (params.user_nm) {
tmp.push(`user_nm="${params.user_nm}"`);
}
if (params.user_pw) {
tmp.push(`user_pw="${params.user_pw}"`);
}
if (params.user_addr) {
tmp.push(`user_addr="${params.user_addr}"`);
}
//--------------
if (tmp.length == 0) {
throw { message : '입력된 값이 없음'};
} else {
sql += `${tmp.toString()} WHERE user_id="${params.user_id}"`;
conn = await mysql.getConnection();
await conn.beginTransaction();
const [ result ] = await conn.query(sql);
rt.ok = true;
rt.msg = 'ok';
rt.result = result;
await conn.commit();
conn.release();
}
} catch (err) {
console.error('userTable/updae Error!!', err);
rt.msg = 'user_update Error';
rt.result = err.message;
if (conn !== null) {
await conn.rollback();
conn.release();
}
}
res.send(rt);
})
업데이트의 경우 변경하고자 하는 필드=값이 입력된 것만 수정하기 위해 위에 처럼 작성함.
스트링을 배열에 담고 해당 변수를 .toString() 하면 콤마 처리까지 깔끔하게 됨.
데이터 delete
router.post('/delete', async (req, res) => {
let rt = {
ok: false,
msg: '',
result: null
}
const params = req.body;
let conn = null;
try {
if (params.user_id === undefined || params.user_id === null || params.user_id === '') {
throw { message : 'parameter user_id is null....'};
}
const sql = `DELETE FROM ${table} WHERE user_id="${params.user_id}"`;
conn = await mysql.getConnection();
await conn.beginTransaction();
const [ result ] = await conn.query(sql);
await conn.commit();
conn.release();
rt.ok = true;
rt.msg = 'ok';
rt.result = result;
} catch (err) {
console.error('userTable/delete Error!!', err);
rt.msg = 'userTable/delete Error';
rt.result = err.message;
if (conn !== null) {
await conn.rollback();
conn.release();
}
}
res.send(rt);
})
추가 내용.
계속 사용하다보니 쿼리를 짜고 커넥션 -> 트랜잭션 -> 쿼리실행 -> 커밋 -> 릴리즈 이런게 소스에서 계속 반복되다보니 기능하나 만들때마다 코드가 길어지고 중복되는 소스가 너무 많았다.
쿼리만 받아서 위 과정을 처리해서 정상처리 되면 결과를, 실패하면 에러를 반환시키는 함수 하나를 만들어서 함수만 쓰는 게 좋을 것 같다는 생각이 들어서 함수를 아래 처럼 만들어줬다.
//runQuery.js
const mysql = require('../../mysql');
function runQuery(sql) {
return new Promise( async (resolve, reject) => {
let conn = null;
try {
conn = await mysql.getConnection();
await conn.beginTransaction(); //트랜잭션 시작
const [ result ] = await conn.query(sql);
await conn.commit(); //커밋
conn.release();
resolve(result);
} catch (err) {
if (conn !== null) {
await conn.rollback(); //롤백
conn.release();
}
reject(err);
}
})
}
module.exports = runQuery;
프라미스 함수로 만들어서 쿼리를 받고 실행 해서 정상이면 resolve로 에러가 발생하면 reject를 주도록 만들어줬다.
실패 시 내부에서 자체적으로 롤백과 릴리즈까지 하게 작성했다.
그리고 사용은 아래 처럼 했다.
const run = require('./runQuery');
router.post('/insert', async (req, res) => {
let rt = {
ok : false,
msg : '',
result : null
}
const params = req.body;
try {
if (isNull(params.user_id)) throw { message : '아이디 없음'};
if (isNull(params.user_nm)) throw { message : '이름 없음'};
if (isNull(params.user_pw)) throw { message : '패스워드 없음'};
const sql = `INSERT INTO ${table} (user_id, user_nm, user_pw, user_addr, user_mk_dt, user_upd_dt, is_use) VALUES (
"${params.user_id}",
"${params.user_nm}",
"${encryptPassword(params.user_pw)}",
"${params.user_addr}",
NOW(),
NOW(),
1
)`;
rt.ok = true;
rt.msg = 'ok';
rt.result = await run(sql);
} catch (err) {
console.error('userTable/insert Error!!', err);
rt.msg = 'user_insert Error';
rt.result = err.message;
}
res.send(rt);
})
맨 위에 있는 insert 부분을 수정한 부분이고, 쿼리 실패시 롤백도 함수에서 실행하기 때문에 사용하는 곳에선 try/catch로 받게 구성만 하고 쿼리만 넘겨주면 된다.
반응형
'Node.js' 카테고리의 다른 글
[NodeJS] 이벤트 디멀티플렉싱과 리액터패턴 (0) | 2022.08.15 |
---|---|
[NodeJS] Error : Cannot overwrite users model once compiled (0) | 2022.06.24 |
[NodeJS] express에서 mysql2 사용하기 (0) | 2022.03.10 |
[NodeJS] express에서 mysql 사용하기 (1) | 2022.03.09 |
[NodeJS] Error: Unable to load PFX certificate 에러 (0) | 2022.02.23 |