강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của spring0073
spring0073

câu hỏi đã được viết

Học thiết kế hệ thống quy mô lớn thông qua việc tự tay xây dựng với Spring Boot - Bảng tin

Triển khai số lượt thích

디비 오류

Đã giải quyết

Viết

·

264

0

  • 학습 관련 질문을 최대한 상세히 남겨주세요!

  • 고민 과정도 같이 나열해주셔도 좋습니다.

  • 먼저 유사한 질문이 있었는지 검색해보세요.

  • 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.

 

mysql 말고 마리아 디비로 진행하고 있는데 다음과 같은 오류가 납니다...

 

 

java.sql.SQLException: (conn=47) Record has changed since last read in table 'article_like_count'

 

그래서 인지 count가 일정하지 않네요.. 이유가 있을까요

javamysqlspring-bootkafkaredis

Câu trả lời 3

0

kuke님의 프로필 이미지
kuke
Người chia sẻ kiến thức

최강개발자님, 안녕하세요!

 

문의주신 내용이 likePerformanceTest에 대한 결과를 말씀하시는게 맞을까요?

낙관적 락은 병렬 처리 시에 충돌이 발생하면, version 값에 의해 변경을 감지하고 실패 및 롤백되는 게 맞습니다.

이러한 동작은 비관적 락처럼 명시적으로 락을 잡진 않지만, 락으로 인한 병목 문제를 방지할 수 있다는 장점이 있습니다.

그래서 충돌이 발생하면 레코드 변경 감지로 인해 트랜잭션 실패에 대한 에러 로그가 남을 수 있습니다.

 

멀티스레드에서 동시 요청을 보냈다면, 비관적 락1, 2 방식은 실패 없이 모두 처리되는게 맞지만(락 타임아웃이 발생하지 않았다면),

낙관적 락은 데이터 충돌이 발생한 경우 일부 요청은 실패해서 더욱 적게 집계될 수 있습니다.

다만, 좋아요 데이터 생성과 좋아요 수 데이터 증가를 트랜잭션으로 묶어서 처리하다보니, 데이터 정합성이 깨지지는 않는 것이고요!

 

낙관적 락 방식으로 API 요청을 멀티스레드에서 병렬로 보냈다면,

실패된 트랜잭션이 있을 수 있으므로 카운트가 상대적으로 적게 나와야할텐데, 모두 성공한 것도 이상하긴 하네요!?

강의 영상에서도 낙관적 락 방식은 실패한 트랜잭션으로 인해 카운트가 적게 집계됩니다.

단일 스레드로 요청을 보냈거나 또는 mysql에 격리 레벨을 임의로 제어하신걸까요?

 

그리고 개발 환경은 웬만하면 강의와 동일하게 맞춰서 진행하는 것을 권장합니다!

InnoDB 기반이라 큰 차이는 없을 것 같긴한데, 제가 모든 타플랫폼과 버전을 사용해본건 아니다보니, 달라지는 부분을 명쾌하게 잡아내서 답변 드리기 어려울 수 있습니다..! (이 부분은 죄송스럽네요 ㅠ)

 

감사합니다.

0

spring0073님의 프로필 이미지
spring0073
Người đặt câu hỏi

자문자답입니다.

 

마리아 디비로 했던것을 mysql로 변경하니 오류가 사라졌습니다.

 

더 깊게 파려고 하였지만,,, 추후 한번 다시 보도록 하겠습니다.

 

신기한건 mysql 최신버전이라 그런지 3개 전부 동일하게 나왔습니다.

 

pessimistic-lock-1end

count =3001

pessimistic-lock-2start

lockType =pessimistic-lock-212060ms

pessimistic-lock-2end

count =3001

optimistic-lockstart

lockType =optimistic-lock11851ms

optimistic-lockend

count =3001

 

0

안녕하세요, 인프런 AI 인턴입니다. 최강개발자님.

현재 마주하신 오류는 MariaDB에서 데이터의 동시성 제어 문제가 발생하는 상황입니다. 이는 트랜잭션 간에 충돌이 발생했을 때 주로 발생하는데, 특히 article_like_count 테이블에서 발생하고 있는 것으로 보입니다.

이유 및 해결 방법:

  1. 비관적/낙관적 락 설정:

    • 낙관적 락(Optimistic Locking): 트랜잭션이 끝날 때 데이터가 수정된 경우에만 충돌을 감지하는 방식입니다. EJB나 JPA에서 @Version 어노테이션을 사용하여 낙관적 락을 적용할 수 있습니다. 이 방식은 주로 충돌이 드문 상황에서 유용합니다.
    • 비관적 락(Pessimistic Locking): 레코드의 잠금을 통해 다른 트랜잭션에서 변경하지 못하도록 보장해 줍니다. JPA에서는 @Lock 어노테이션을 사용하여 비관적 락을 구현할 수 있습니다.
  2. 트랜잭션 격리 수준 (Isolation Level) 변경:

    • 트랜잭션의 격리 수준을 조정해보세요. 기본값을 READ COMMITTED로 설정하면 필요한 경우 격리 수준을 SERIALIZABLE 또는 REPEATABLE READ로 조정하여 레코드의 일관성을 높일 수 있습니다.
  3. MariaDB 특성 반영:

    • MariaDB와 MySQL은 유사하지만 특정 동작에서 차이가 날 수 있습니다. MariaDB의 설정이나 트랜잭션 동작을 재확인하시고 그에 맞춰 코드를 조정해 보시기 바랍니다.

추가 자료 및 유사 글:

비슷한 문제를 마주한 다른 개발자들의 사례를 참고하시길 권해드립니다:
- MariaDB의 트랜잭션 문제해결 실습 예제.

저는 질문자님의 문제 해결을 돕기 위해 유사한 기존의 질문 링크를 포함하여 답변을 제공하고 있으며, 현재 베타 기능으로 답변이 충분하지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면 언제든지 문의해주세요. 곧 지식공유자께서 추가적인 답변을 제공해 드릴 것입니다.

Hình ảnh hồ sơ của spring0073
spring0073

câu hỏi đã được viết

Đặt câu hỏi