DB/MySQL

트랜젝션 :: 프로시져 활용

put-stacker 2020. 7. 6. 10:40

MySQL 의 단점 중하나는 Commit 과 RollBack 인 것 같다.

기본적으로 Transaction ( 절차 ) 관련 기능이 부재하여 이를 Procedure를 구성하여 대체할 수 있다.

Procedure ( 함수 ) 의 장점은 오류가 발생할 경우, 모든 작업은 RollBack 할 수 있다.

그렇다면, 여기서 Error를 Catch 하는 방법이 가장중요하다.

 

Procedure 를 Call 할 때의 Params 오류는 코드작성 시 별도로 확인해주어야하지만,

Procedure의 내부에서 발생한 오류는 SQLEXCEPTION 의 핸들러를 활용하여 기록할 수 있다.

 

코드는 아래의 목적을 표현하기위해 작성되었다.

1. Error Logging

2. Json Parsing

3. Transaction

4. Return Check

5. Get Increment key value

 

DROP PROCEDURE IF EXISTS `DAO_PROCEDURE`
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `DAO_PROCEDURE`(
	OUT RESULT INT,
    OUT _ID INT,
	# Params
        IN $id INT
)
BEGIN
    DECLARE _WR_OPTION VARCHAR(100);
    /* 에러로그 관련 변수 */
    DECLARE v_vch_proc_name varchar(100) DEFAULT 'DAO_PROCEDURE';
    DECLARE v_iny_proc_step tinyint UNSIGNED DEFAULT 0;
    DECLARE v_txt_call_stack text;
    DECLARE v_vch_sql_state varchar(5);
    DECLARE v_int_error_no int;
    DECLARE v_txt_error_msg text;
	/* 만약 SQL에러라면 ROLLBACK 처리한다. */
	DECLARE exit handler for SQLEXCEPTION
	  BEGIN
        GET DIAGNOSTICS CONDITION 1 v_vch_sql_state = RETURNED_SQLSTATE
            , v_int_error_no = MYSQL_ERRNO
            , v_txt_error_msg = MESSAGE_TEXT;
 
        ROLLBACK;
 
        SET v_txt_call_stack = CONCAT('{"mb_id":', IF($mb_id IS NULL, 'null', $mb_id)
            , ',"action":', CONCAT("INSERT SAMPLE : ", $title_kor)
            , ',"datetime":', $wr_datetime
            , '}'
        );
 
        INSERT `error_log` (`proc_name`, `proc_step`, `sql_state`, `error_no`, `error_msg`, `call_stack`, `proc_call_date`, `log_date`)
        VALUES (v_vch_proc_name, v_iny_proc_step, v_vch_sql_state, v_int_error_no, v_txt_error_msg, v_txt_call_stack, $wr_datetime, NOW(0));
 
        SET RESULT = -1;
 
        RESIGNAL;
	END;

	/* 트랜젝션 시작 */
	START TRANSACTION;
		/* TABLE 정보입력 */
			INSERT INTO `Table`
			(`Columns`, ..., `Columns`) 
			VALUE
			(`Values`, ..., `Values`);
		/* FK_ID :: REFERENCSING */
			SET _ID = last_insert_id();
            
	/* 커밋 */
	COMMIT;
	SET RESULT = 0;
END$$
DELIMITER ;