TIL_2023.07.07

이얏호·2023년 7월 7일
0

어제 TIL에 올렸던 오류 사항에 대해서 정확한 이유를 찾았다.
튜터님께 transaction 오류 혹은 교착상태 시 상태를 확인하는 법 역시 배웠다.

답은 결국 sequelize에서의 transaction 사용법에 있었는데
우선 오류난 코드를 다시 적어보자면

		await Likes.create(
        {
          UserId: userId,
          PostId: postId,
        },
        { transaction: t }
      );
      await Posts.update(
        { likeCount: post.likeCount + 1 },
        { where: { postId } },
        { transaction: t }
      );

다음과 같다.

여기서 Posts.update 부분의 {transaction:t} 부분에 문제가 있었다.
문제가 해결된 코드는

		await Likes.create(
        {
          UserId: userId,
          PostId: postId,
        },
        { transaction: t }
      );

      await Posts.update(
        { likeCount: post.likeCount + 1 },
        { where: { postId }, transaction: t }
      );

이렇게 transaction의 위치가 where절과 같은 레벨에 존재해야 정상 작동을 했다...

아무래도 sequelize 문법에 대한 이해가 부족했고
단순하게 두 번째 인자에 집어넣는다는 이야기를 듣고 where절 이후에 집어넣었는데 그 부분이 결국 문제였다.


오류를 해결해보려고 시도하면서 단순하게 update와 create의 위치만 서로 바꾸었을 때, 황당하게도 작동하던 상황이 발생했는데
생각해본 이유는 다음과 같다.

		await Posts.update(
        { likeCount: post.likeCount + 1 },
        { where: { postId } },
        { transaction: t }
      );
        await Likes.create(
        {
          UserId: userId,
          PostId: postId,
        },
        { transaction: t }
      );

위와 같이 transaction 부분이 잘 못 작성된 update문이 위에 존재할 경우, 2번째 인자 안에서 where 절과 함께 넘어왔어야 할 transaction: t 구문이 존재하지 않기 때문에 transaction자체가 실행되지 않고 하단에 있는 create부분에서는 이상이 없었기 때문에 결과적으로 로직이 정상작동한 것으로 보인다.

반대로 update가 create의 아래에 존재할 경우, create 구문에서 transaction이 실행되었지만 update부분의 정상적인 위치에서 transaction: t이 존재하지 않았기 때문에 transaction을 찾지 못해서 무한 로딩에 걸리다가 rollback 된 것으로 판단 되어 진다.



여기까지 문제의 원인과 오류 해결중에 도대체 왜 순서만 바꿨는데 작동했는지에 대한 원인 분석이었고 아래는 튜터님이 알려주신 현재 db 상태 확인 관련한 쿼리문 메모이다...
(기억 용도)

show engine innodb status
엔진상태확인

show processlist
프로세스상태확인

information_schema 테이블 => INNODB_TRX을 셀렉트해서 확인하는방법도 존재
SELECT @@global.transaction_isolation;
글로벌 격리 레벨 확인
select @@session.transaction_isolation;
해당 세션 격리 레벨 확인

오류들을 확인하면서 발견했는데
아래와 같이 세션의 격리 레벨을 READ-UNCOMMITTED로 바꿔주었으나

set @@session.transaction_isolation = 'READ-UNCOMMITTED';

해당 쿼리문은 session의 격리 레벨을 READ-UNCOMMITTED로 변경하는 구문

select @@session.transaction_isolation;
show variables like 'transaction_isolation';

아래 두 줄은 격리 레벨 확인

위와 같이 작성을 하면 순간적으로 격리 레벨이 바뀌어
select @@session.transaction_isolation; 부분에서 정상적으로 READ-UNCOMMITTED로 찍히지만
바로 다시 select @@session.transaction_isolation;만 찍어보면 REPEATABLE_READ로 돌아가있는 현상을 발견했다.

=> 해당부분은 아마 내가 RDS를 사용 중이라 기본적인 설정 관련해서 디폴트 값이 REPEATABLE_READ로 지정된 상태라 강제 변경이 안되는 것으로 추정 중...

profile
열심히 신나게 화이팅!

0개의 댓글