본문 바로가기

카테고리 없음

MySQL 성능 개선 프로젝트 5

하나의 트리거안에 여러가지 작업을 실행시키는것보다 작업들을 각각의 프로시저로 만든다음 전체를 실행시켜주는 프로시저로 나누었다. 

이렇게 한 이유에는 한 트리거안에 복잡한 작업들이 여러개 실행된다면 성능저하가 우려되고, 또한 그 중 한가지 작업이라도 에러가 발생한다면 모두 롤백되기 때문이다.

이를 프로시저로 바꾼다면 성능저하도 해결할 수 있고, 또한 트랜잭션을 관리해줌으로써 중간에 에러가 발생하더라도 꼭 필요한 데이터에 대한 작업은 실행이 될것이다.

delimiter //
DROP procedure if EXISTS insert_delivery_processing;
CREATE PROCEDURE insert_delivery_processing(in updated_order_id BIGINT)
BEGIN
	DECLARE selected_dv_order_id BIGINT;
	
	DECLARE exit handler FOR SQLEXCEPTION
	BEGIN
		ROLLBACK;
		
		INSERT INTO transaction_log(
			message,
			order_id
		) VALUES(
			'insert_delivery_processing 프로시저 에러 발생',
			updated_order_id
		);
	END;
	
	START TRANSACTION;	
	
	CALL insert_delivery_order(updated_order_id, selected_dv_order_id); -- 트랜잭션 관리를 어떻게 할것인가
	
	COMMIT;
	
	START TRANSACTION;	
	
	CALL insert_chat_channel(selected_dv_order_id);
	
	COMMIT;
	
	START TRANSACTION;	
	
	CALL insert_delivery_insurance(selected_dv_order_id);
	
	COMMIT;
END //
delimiter ;

drop procedure insert_delivery_processing;

 

exit handler를 이용해서 이 통합 프로시저에 에러가 발생할 경우 로그가 테이블에 생성되게했다.

이 과정에서 에러가 발생되어 롤백이 되는데도 계속 로그테이블에 기록이 생성되지않는 문제가 발생했는데,

문제는 에러테이블의 INSERT문과 핸들러의 ROLLBACK의 위치가 잘못되어서였다.. 

 

DECLARE exit handler FOR SQLEXCEPTION
	BEGIN
      		
		INSERT INTO transaction_log(
			message,
			order_id
		) VALUES(
			'insert_delivery_processing 프로시저 에러 발생',
			updated_order_id
		);
    	
		ROLLBACK;
	END;

 

이렇게 될 경우 insert문이 실행되어도 이후에 ROLLBACK이 실행되어 INSERT문이 롤백되어버린다.