IT's Jenna

Database 상태변화 본문

Backend/Backend 기본

Database 상태변화

developer Jenna 2021. 1. 27. 12:54
목표 : DB에 CRUD 동작을 하는 쿼리문을 만들어 보자

1. createPool

우선 express를 활용해서 goods라는 라우팅 환경을 하나 만들었다.

 

여기서 mysql과 통신해서 쿼리문을 동작시키고자 한다. 이때 서버와 mysql의 연결을 위해 사용하는 것이 createPool이다. Pool은 database 연결 캐시*이다. Pool을 사용하면 다수의 connection을 관리할 수 있고, 매번 connection을 새로 만들 필요 없이 기존의 connection을 재활용할 수 있다.

 

  • 캐시 : 데이터나 값을 미리 복사해둔 임시 장소. 데이터에 접근하는 시간이나 계산하는 시간이 오래 걸릴 때 시간을 절약하기 위해 미리 복사본을 만들어 둔 것

아래와 같이 config라는 폴더 내 index.js파일에 database정보를 입력했다. (실무에는 파일에 database 정보를 담지 않고 환경변수를  가져와서 사용한다) module.exports는 해당 내용을 외부 파일에서 읽을 수 있도록 export 한다는 의미다.

module.exports = {
    database: {
        host : '127.0.0.1',
        user : 'root',
        password : '내 비밀번호',
        database : 'sys',
        port: '3306',
        connectionLimit : '10',
        timezone : 'utc',
        debug : ['ComQueryPacket', 'RawDataPacket']
    }
}

config = require('../config')로 위의 index.js 파일을 불러올 수 있다. 폴더 안의 파일명을 적지 않으면 바로 index파일을 가져온다. 그리고 createPool을 해서 Pool을 생성해준다.

var express = require('express');
var router = express.Router();

const config = require('../config') 
const mysql = require('mysql');
const { json } = require('express');

const pool = mysql.createPool({
    connectionLimit : config.database.connectionLimit,
    host : config.database.host,
    user : config.database.user,
    password : config.database.password,
    database : config.database.database
})

2. beginTransaction & rollback & commit

실제로 Database와 연결되어야 할 때 pool.getConnection을 통하여 pool에서 연결을 받아온다.

 

연결을 받아온 후 beginTransaction으로 동작을 시작한다. 이때 Transaction은 Database 상태를 변화시키기 위해 작업하는 단위이다. 이 Transaction은 쿼리 한 문장이 아니다. 예를 들어, 사용자의 정보를 받고 그 정보를 Database에 추가한 후 다시 Filtering 하여 화면에 나타내 준다면, Insert, Select가 함께 사용된 것이다. 이렇게 개발자가 설계한 하나의 작업 단위를 Transaction이라고 한다.

 

Transaction 안에서 동작되어야 하는 것이 rollbackcommit이다.

rollback은 어떤 동작을 수행 중에 에러가 발생한 경우 해당 동작을 무효화한다. 아래 connection.query 에서 쿼리문에 에러가 있다면 rollback으로 동작을 무효화한다. 그리고 connection.release()로 database와의 연결을 다시 pool에 반납한다.

 

commit은 실질적으로 동작을 수행하는 함수이다. commit이 실행되면 하나의 Transaction이 완벽하게 끝났다는 의미다. commit을 수행할 때도 역시 rollback을 통해 에러를 잡아주고 Transaction이 완료되었기 때문에 연결을 반납한다.

router.post('/', function(req, res, next) {
    const body = req.body
    console.log('body : ', body)

    pool.getConnection(function(err, connection){ 
        if (err) throw err
        console.log('connected')

        connection.beginTransaction(function(err){ 
            if (err) { throw err } 
            connection.query( 
                'INSERT INTO Goods SET ?',
                body,
                function (error, result, fields){
                    if (error) {
                        connection.release() 
                        return connection.rollback(function(){ 
                            res.status(200).json({error:error})
                        })
                    } 
                    connection.commit(function(err) {
                        connection.release()
                        if (err) {
                            return connection.rollback(function(){
                                res.status(200).json({error:err})
                            })
                        }
                        res.status(200).json({result})
                    }) 
                }
            )
        })
    })
    
  });

3. Put & Delete & Get

Post를 작성했으면 Put과 Delete는 query문만 바꿔주면 된다.

//Put
let newGood = {name : body.name, price: body.price}
'UPDATE Goods SET ? WHERE idx = ?', [newGood, body.idx]

//Delete
'DELETE FROM Goods WHERE idx= ?', body.idx

하지만 Get method는 조금 다르다. 데이터를 받아오기만 하고 Database에 동작하는 것은 없기 때문에 Transation을 할 필요가 없다. 또한 데이터를 지속적으로 받아야 와하므로 Database와의 연결을 계속해서 유지하고 있어야 한다.

router.get('/', function(req, res, next) {
    const {idx} = req.query //localhost:3000/goods?idx=4
    pool.getConnection(function(err, connection){ 
            connection.query( 
                'SELECT * FROM Goods', idx,
                function (error, result, fields){
                    if (error) {
                            res.status(404).json({result:false})
                    }
                    res.status(200).json({result})
                }
            )
        })
    });

 

이렇게 Database에서 CRUD 상태 변화하는 방법을 알아보았다. 다음 포스팅에선 해당 스크립트를 어떻게 실무적으로 편하게 사용할 수 있는지 이야기해보도록 하겠다.

 

<참고>

techbless.github.io/2020/01/17/Node-js%EC%97%90%EC%84%9C-Mysql-Connection-Pool-%EC%9D%B4%EC%9A%A9%ED%95%98%EA%B8%B0/

mommoo.tistory.com/62

'Backend > Backend 기본' 카테고리의 다른 글

Crypto  (0) 2021.02.01
모듈화  (0) 2021.01.27
Callback & Promise & async & await  (0) 2021.01.27
Injection attak  (0) 2021.01.23
Express 환경 사용하기 3 - 라우팅  (0) 2021.01.20
Comments