Article(3)
-
좋아요 동시성 제어 과정
문제 상황이 글은 프로젝트에서 진행했던 좋아요 동시성 제어 과정에 대한 글이다. 앞서 게시글 페이징 조회 성능 개선을 위해 좋아요 수(likeCount)를 게시글 엔티티의 필드로 추가하면서, 동시성 제어가 필요해졌다. (https://olsohee.tistory.com/169) 동시성 제어가 필요한 상황은 다음 두 경우가 있다.사용자는 같은 게시글에 좋아요를 2개 이상 누를 수 없다.여러 명의 사용자가 동시에 같은 게시글에 좋아요를 누를 경우 해당 게시글의 좋아요 수가 덮어 씌워지면 안 된다.기존 코드에서 두 경우를 테스트한 결과, 두 경우 모두 데드락이 발생했다. 데드락의 원인은 MySQL이 조회하는 레코드에 외래 키가 있을 때, 외래 키에 해당하는 테이블 레코드에 S락을 걸기 때문이다. 즉, 게시글 ..
2024.08.20 -
MySQL의 갭 락과 넥스트 키 락에 대해
프로젝트에서 MySQL을 사용하며 락과 트랜잭션 격리 수준에 대한 문제를 여러 번 마주했었다. 이번 기회에 좀 더 제대로 알고자 글을 쓴다. InnoDB 스토리지 엔진 잠금InnoDB 스토리지 엔진은 MySQL에서 제공하는 잠금과는 별개로 스토리지 엔진 내부에서 레코드 기반의 잠금 방식을 제공한다. 따라서 MyISAM보다 훨씬 뛰어난 동시성 처리를 제공할 수 있다. 또한 레코드 락뿐 아니라 레코드와 레코드 사이의 간격을 잠그는 갭 락이라는 것도 제공한다. InnoDB 스토리지 엔진은 인덱스 레코드에 락을 건다InnoDB 스토리지 엔진은 레코드를 잠글 때, 레코드 자체가 아니라 인덱스의 레코드를 잠근다. 인덱스가 하나도 없는 테이블이더라도 내부적으로 자동 생성된 클러스터 인덱스를 이용해 잠금을 설정한다...
2024.08.01 -
서비스 계층에 @Transactional 어노테이션을 붙이는 것에 대한 고찰
@Transactional 어노테이션스프링은 AOP를 통해 트랜잭션 시작과 종료를 간편하게 할 수 있도록 지원한다. 덕분에 @Transactional 어노테이션을 통해 비즈니스 로직에 트랜잭션 관련 로직이 섞이지 않을 수 있다. 트랜잭션 처리 로직은 프록시 객체가 가져가고, 서비스 계층에는 순수한 비즈니스 로직만 남길 수 있게 해준다. @Transactional을 적용했을 때 동작 과정은 다음과 같다.트랜잭션을 시작하기 위해서는 먼저 커넥션이 필요하다.커넥션을 획득했으면, 해당 커넥션을 통해 auto commit 속성을 false로 설정한다. 즉, 트랜잭션이 시작되었고, 이후 진행되는 로직들은 DB에 바로 반영되지 않고 커밋 시점에 반영된다.이후 서비스 계층 내에서 DB에 접근하는 메서드가 실행되면 해당..
2024.07.20