withbible / -deprecated-withbible-server

한국성서대학교 성경졸업고사 퀴즈앱 API서버
1 stars 0 forks source link

AFTER INSERT 트리거 중복키 이슈 대안 #1

Closed kimdev0206 closed 1 year ago

kimdev0206 commented 1 year ago

quiz_user_option 테이블에는 AFTER INSERT 트리거를 장착해두었습니다.

자세한 설명은 ERD 안에 기술하였습니다. (ERD 확인하러 가기)

트리거 발생시, 대상이 되는 테이블에 Duplicate entry '2-1' for key 'quiz_chapter_user_state.PRIMARY 라는 중복키 에러가 발생했습니다.

해당 테이블은 pk 2개로 고유성을 유지합니다. (chapter_seq, user_seq) 테이블에 중복된게 없음에도 트리거 안에 INSERT 구문이 발생하지 않았습니다.

원인파악을 하진 못했고 현재로써는 대안으로 ON DUPLICATE UPDATE를 사용하였습니다.

수정전 트리거 쿼리

TRIGGER `quiz_user_option_insert` 
AFTER INSERT ON `quiz_user_option` 
FOR EACH ROW BEGIN
    ...
    DECLARE new_hit_question_count TINYINT;

    ...
    SET new_hit_question_count = (
        SELECT  
            COUNT(uo.question_option_seq)
        FROM quiz_question_option AS qo 
        LEFT JOIN quiz_user_option AS uo    
            ON qo.question_option_seq = uo.question_option_seq 
        WHERE qo.answer_yn = 1
        GROUP BY
            uo.chapter_seq,
            uo.user_seq
        HAVING uo.chapter_seq = NEW.chapter_seq
            AND uo.user_seq = NEW.user_seq
    );

    ...

    INSERT INTO quiz_chapter_user_state
        (chapter_seq, user_seq, active_question_count, hit_question_count)
    VALUES(
        NEW.chapter_seq,
        NEW.user_seq,
        new_active_question_count,
        IFNULL(new_hit_question_count, 0)
    );
END

수정후 트리거 쿼리

TRIGGER `quiz_user_option_insert`
AFTER INSERT ON `quiz_user_option` 
FOR EACH ROW BEGIN
    ...
    DECLARE new_hit_question_count TINYINT;

    ...
    SET new_hit_question_count = (
        SELECT  
            COUNT(uo.question_option_seq)
        FROM quiz_question_option AS qo 
        LEFT JOIN quiz_user_option AS uo    
            ON qo.question_option_seq = uo.question_option_seq 
        WHERE qo.answer_yn = 1
        GROUP BY
            uo.chapter_seq,
            uo.user_seq
        HAVING uo.chapter_seq = NEW.chapter_seq
            AND uo.user_seq = NEW.user_seq
    );

    ...

    INSERT INTO quiz_chapter_user_state
        (chapter_seq, user_seq, active_question_count, hit_question_count)
    VALUES(
        NEW.chapter_seq,
        NEW.user_seq,
        new_active_question_count,
        IFNULL(new_hit_question_count, 0)
    ) ON DUPLICATE KEY UPDATE
        chapter_seq = VALUES(chapter_seq),
        user_seq = VALUES(user_seq);
END