인프런 커뮤니티 질문&답변
작성자 없음
작성자 정보가 삭제된 글입니다.
lockType 오류 및 카운트 체크 안 됨
해결된 질문
작성
·
21
0
안녕하세요! 강의 잘 듣고 있습니다. 좋은 강의 감사합니다.
실습하다가 오류가 생겨 문의 드립니다.
void like(Long articleId, Long userId, String lockType) {
restClient.post()
.uri("/v1/article-likes/articles/{articleId}/users/{userId}/" + lockType, articleId, userId)
.retrieve();
}
@Test
void likePerformanceTest() throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(100); // 100개의 스레드 풀 생성
// 각 lock type별로 테스트
likePerformanceTest(executorService, 1111L, "pessimistic-lock-1");
likePerformanceTest(executorService, 2222L, "pessimistic-lock-2");
likePerformanceTest(executorService, 3333L, "optimistic-lock");
}
void likePerformanceTest(ExecutorService executorService, Long articleId, String lockType) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(3000);
System.out.println(lockType = " start");
like(articleId, 1L, lockType);
long start = System.nanoTime();
for (int i = 0; i < 3000; i++) {
long userId = i + 2;
// String finalLockType = lockType;
executorService.submit(() -> {
like(articleId, userId, lockType);
latch.countDown();
});
}
latch.await();
long end = System.nanoTime();
System.out.println("lockType = " + lockType + ", time = " + (end - start) / 1_000_000 + " ms");
System.out.println(lockType + " end");
Long count = restClient.get()
.uri("/v1/article-likes/articles/{articleId}/count", articleId)
.retrieve()
.body(Long.class);
System.out.println("count = " + count);
}여기서 '람다 식에 사용되는 변수는 final 또는 유사 final이어야 합니다' 라는 오류가 뜨더라고요.
// String finalLockType = lockType; 부분 주석 해제하고 람다 내부에 like(articleId, userId, finalLockType); 으로 하면
start
lockType = start, time = 914 ms
start end
count = 0
start
lockType = start, time = 589 ms
start end
count = 0
start
lockType = start, time = 567 ms
start end
count = 0
으로 출력도 잘 안 나옵니다.
애플리케이션 콘솔에는 아래 로고만 찍히고 나머지는 안 나옵니다.
Hibernate: select alc1_0.article_id,alc1_0.like_count,alc1_0.version from article_like_count alc1_0 where alc1_0.article_id=?
Hibernate: select alc1_0.article_id,alc1_0.like_count,alc1_0.version from article_like_count alc1_0 where alc1_0.article_id=?
Hibernate: select alc1_0.article_id,alc1_0.like_count,alc1_0.version from article_like_count alc1_0 where alc1_0.article_id=?
어느 부분이 문제일까요?
ArticleLikeController에서 count 경로는 테스트처럼 뒤에 /count 추가했습니다.
답변 2
0
안녕하세요!
위 내용만 보고는 원인 파악이 어렵네요, 혹시 스프링부트 버전이 강의와 다를까요?
최신 버전에서는 restClient에서 retrieve()까지만 하면 실제 api 호출이 안될 수 있어서, retrieve().toBodilessEntity()까지 호출해보시겠어요?
0
안녕하세요, 인프런 AI 인턴입니다. sally0109277님.
제시해주신 코드에서 나타난 문제를 해결하기 위한 몇 가지 접근 방법을 제시드리겠습니다.
1. ‘람다 식에 사용되는 변수는 final 또는 유사 final이어야 합니다’ 오류
람다식에서 외부 변수를 사용하려면 해당 변수는 final이거나, 사실상 final이어야 합니다. 이 오류는 실제로 발생할 수 있는데, lockType 변수를 람다 내에서 수정하지 않아야 합니다. 이미 시도하신 것처럼 finalLockType 으로 복사하여 사용하시면 잘 해결할 수 있습니다.
String finalLockType = lockType;
executorService.submit(() -> {
like(articleId, userId, finalLockType);
latch.countDown();
});
2. LOCK_TYPE 사용 문제
현재 오류의 원인 중 하나로 보이는 부분은 lockType 초기화 또는 호출 방식에 있다 할 수 있습니다. 특정 lockType을 사용하고 해당 부분이 서비스 로직에 영향을 미치는지를 먼저 분석할 필요가 있습니다.
- lockType 변수의 정확한 사용 확인:
like메서드에서 전달된 마이크로서비스나 컨트롤러가 lockType을 제대로 수용하여 처리하고 반환 결과에 반영되었는지 확인합니다.
3. 로그 및 트랜잭션 검토
Hibernate 로그: 제공된 로그는 JPA를 사용하여 데이터 접근 시 발생하는 SQL을 보여줍니다. 여기서
count=0이라는 결과는 데이터베이스에 올바른 insert가 이루어지지 않을 가능성이 있습니다. 트랜잭션이나 데이터베이스 연결에서의 문제를 확인할 필요가 있습니다.데이터베이스 상태: 테스트 환경에서 관련 데이터베이스 설정과 테스트 데이터가 적절하게 초기화되어 있는지 확인해야 합니다. 예를 들어, ArticleLikeCount와 관련된 데이터가 트랜잭션 내에서 올바르게 갱신되는지 점검하는 것이 필요합니다.
4. 테스트 전 결과 예측
- 테스트 기대 결과: 테스트 전에 성공 사례와 예상 결과와 비교하여 모든 조건을 충족하고 있는지를 검증해야 합니다.
관련하여 유사한 문제를 해결하는데 도움이 되는 링크를 제공해드립니다:
- Java Lambda Expressions and Variable Capture
저는 질문자님의 이해를 돕고자 유사한 해결 방법을 안내드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드리며, 추가적으로 궁금한 사항이나 다른 문제가 있다면 계속해서 질문 주세요. 곧 지식공유자께서 추가적인 답변을 제공해 주실 것입니다. 🙏





