회고록 (24.05.27 - 24.06.02 )

JSLEE·2024년 6월 2일

1. 공부했던 내용들

  1. BookShop 프로젝트 :

    • 좋아요 API 구현
    • 장바구니 API 구현
    • 주문 API 구현
  2. 사용한 기술 스택 :

    • SQL - count(), AS, 서브 쿼리, EXISTS
    • FK 이름 중복 해결
    • LAST_INSERT_ID(), MAX(), results.insertId
    • 비동기 처리 - Promise, async, await
    • 테이블 초기화 - TRUNCATE
    • 참조 무결성 중단 - SET FOREIGN_KEY_CHECKS = 0

2. 궁금했던 점들

Q. express-validator 에서, decode와 verify는 무슨 차이?

└ A.

  • decode : JWT를 디코딩하여 payload를 반환 - signature을 검증하지 않음.
    따라서, 단순히 토큰의 payload 값을 확인하려는 경우에 사용.
let token = jwt.sign({name:"kim"}, SECRET_KEY )
let decoded = jwt.decode(token)
  • verify : JWT를 디코딩 하기 전에 signature을 검증하고, 옳은 토큰인 경우에 payload 값을 반환, 서버의 SECRET KEY가 필요함.
let token = jwt.sign({name:"kim"}, SECRET_KEY )
let decoded = jwt.verify(token, SECRET_KEY)

JWT의 목적은 사용자를 인증하기 위한 목적이기 때문에,
웬만하면 decode 대신 verify만 사용한다고 보면 될 것 같다.


Q. mysql2 모듈은 commit 기능을 지원하는가? (여러 테이블에 데이터를 삽입하는 과정에서, 일부 테이블에서 오류가 발생했을 때, 다시 되돌릴수 있는가? )

A.
mysql2 모듈은 commit&rollback 을 지원한다.
예를 들어 A,B,C라는 3개의 테이블이 있고, 하나의 API에서 3개의 테이블에 데이터를 넣는다고 생각해보자.
A테이블에 데이터를 정상적으로 INSERT했는데, B테이블에서 오류가 발생했다.
이 때는 오류 respond를 보냄과 동시에, A테이블은 다시 원래 상태로 되돌려야 한다.
이 때 사용하는 것이 conn.biginTransaction() , conn.commit() , conn.rollback() 메소드 이다.
다음과 같은 세 테이블이 있다고 생각해보자.

이 테이블들의 컬럼들은 모두 INT 자료형을 가진다.
두번째 테이블문자열 자료형을 INSERT하면서 의도적으로 오류를 발생시켜보자.

app.get("/", async (req, res) => {
  const conn = await mysql.createConnection({...})

  try {
    let sql = `INSERT INTO myTable1 VALUES (?,?)`;
    let values = [4, 14];
    await conn.query(sql, values);

    sql = `INSERT INTO myTable2 VALUES (?,?)`;
    values = [4, "문자데이터"];
    await conn.query(sql, values);

    sql = `INSERT INTO myTable3 VALUES (?,?)`;
    values = [4, 34];
    await conn.query(sql, values);

    res.status(200).send("OK")
  } catch (err) {
    res.status(400).json(err)
  }
})

이제, Postman을 이용해 GET 메소드를 Request해보겠다.

  • 결과

Workbench

Postman

두번째 테이블부터는 에러가 발생하여 데이터가 삽입되지 않았고, 첫번째 테이블은 INSERT가 수행되었다.
그렇다면, conn.biginTransaction() , conn.commit() , conn.rollback() 를 사용하면 어떤 결과가 나올까? ( 첫번째 테이블의 4번째 데이터는 삭제 후 수행하였다. )

app.get("/", async (req, res) => {
  const conn = await mysql.createConnection({...});

  try {
    conn.beginTransaction(); // 추가됨

    let sql = `INSERT INTO myTable1 VALUES (?,?)`;
    let values = [4, 14];
    await conn.query(sql, values);

    sql = `INSERT INTO myTable2 VALUES (?,?)`;
    values = [4, "문자데이터"];
    await conn.query(sql, values);

    sql = `INSERT INTO myTable3 VALUES (?,?)`;
    values = [4, 34];
    await conn.query(sql, values);

    await conn.commit(); // 추가됨

    res.status(200).send("OK")
  } catch (err) {
    await conn.rollback(); // 추가됨
    res.status(400).json(err)
  }
})
  • 결과
    Workbench

    Postman

Postman에서는 여전히 에러 메시지를 출력하지만, 1번 테이블을 확인해보면 입력했던 값이 취소된 것을 확인할 수 있다.
즉, 테이블의 변화를 일시적으로 보류하고 있다가, commit 명령이 내려지면 한 번에 쿼리문을 수행하고, 에러가 발생하면 원래 상태로 Rollback 시킨다.

이 기능은 유용하게 사용할 것 같으므로 외워둬야겠다.


Q. 배열의 비구조화 vs 객체의 비구조화

//배열의 비구조화
let myArr = [1,2,3]
let [a, b, c] = myArr
console.log(a, b, c); // 1 2 3

배열의 비구조화는 인덱스를 기준으로 할당된다.
즉, 요소들의 순서가 중요하다.

//객체의 비구조화
let myObj = { "a" : 1 , "b" : 2 , "c" : 3 }
let {c , b , a} = myObj
console.log(a,b,c) // 1 2 3

객체의 비구조화는 key값을 기준으로 할당된다.


Q.createPool( ) VS .createConnection( )

A. createPool과 creatConnection의 차이

profile
공부한 내용들을 정리하기 위해 사용하는 블로그입니다.

0개의 댓글