지난번에 문제가 되었던 아래 링크를 보시면 
2023.04.27 - [Spring] - spring vue 연동 게시판 03

 

spring vue 연동 게시판 03

음 지금 다 완성했는데 몇가지 문제가 좀 발생했어요 오류코드는 아래에 있습니다. 게시판글 등록이랑 데이터들은 잘 조회되는데 디테일 조회시 jdbc에서 db가 끊기는 현상이 발생합니다. 그래서

kwaksh2319.tistory.com

마지막에 게시글들이 안보였죠 
 
결론부터말하자면 connection pooling을 사용하지 않았고 entityManager.close();가 되지 않아서 문제가 되었던 헤픈닝이었습니다.
pooling-size 2개로도 충분히 돌아간다는 사실을 알게되었습니다.

public List<Product> findAll(int page, int size) {
        List<Product> productList = null;
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        try{
            CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
            CriteriaQuery<Product> criteriaQuery = criteriaBuilder.createQuery(Product.class);

            Root<Product> root = criteriaQuery.from(Product.class);
            criteriaQuery.select(root);

            TypedQuery<Product> typedQuery = entityManager.createQuery(criteriaQuery);
            typedQuery.setFirstResult((page - 1) * size);
            typedQuery.setMaxResults(size);
            //    criteriaQuery.where(criteriaBuilder.equal(root.get("id"), 1)); 조건 추가시
            // 페이지 조건
             productList = typedQuery.getResultList();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(entityManager!=null){
                entityManager.close();
            }
        }
        return productList;
    }

기존에 아래 코드를 넣지 않았습니다.

 entityManager.close();

이를 해결하고나서 프로그램들이 해결되었습니다. 
 
이런 비슷한 상황이어서 아래 링크를 보면서 원인을 찾게되었고 해결방법을 알게되었습니다.
 
원인 및 해결 
제가 참고한 사이트 
https://techblog.woowahan.com/2664/

 

HikariCP Dead lock에서 벗어나기 (이론편) | 우아한형제들 기술블로그

{{item.name}} 안녕하세요! 공통시스템개발팀에서 메세지 플랫폼 개발을 하고 있는 이재훈입니다. 메세지 플랫폼 운영 장애를 바탕으로 HikariCP에서 Dead lock이 발생할 수 있는 case와 Dead lock을 회피할

techblog.woowahan.com

문제발생:
Message Queue의 consumer thread 갯수보다 HikariCP의 maximum pool size를 충분하게 설정하지 못해 Dead lock이 발생하여 이번 장애로 이어지게 되었습니다
-우아한 형제들 기술블로그-
 
해결방법:
HikariCP wiki에서는 이 공식대로 Maximum pool size를 설정하면 Dead lock을 피할 수 있다고 합니다.
위의 공식은 이론적으로 Dead lock을 피할 수 있는 최소한의 Pool size 입니다.
공식대로라면 Thread가 몇 개이든 동시에 필요한 Connection이 1개라면
Pool size가 1개인 Pool을 가지고도 모든 Request를 다 처리할 수 있을 것 입니다.
하지만 효율이 좋지 않겠죠.
어떤 Thread는 운이 없게 할당받지 못해서 30초 후에 SQLTransientConnectionException을 던질 수도 있습니다.
그렇기 때문에 최적의 Pool Size를 설정하기 위해서는 Dead lock을 피할수 있는 pool 갯수 + a가 되어야 합니다.
이에 대한 방법으로는 성능 테스트를 수행하면서 최적의 Pool Size를 찾는 방법이 있을 것 같습니다.
-우아한 형제들 기술블로그-

SQL Error: 0, SQLState: null
HikariPool-1 - Connection is not available, request timed out after 60005ms.

우아한 형제들이란는 기술블로그에서 동일한 오류가 발생했습니다. 이때 아 deadlock이 걸린거구나라는걸 알았게되었습니다.
 
처음에는 pooling size 문제인가 생각해서 사이즈를 늘려보니 해결은 되었습니다.(임시방편으로는)
 그런데 아무리 생각해도 pooling size 100개를 넘길 이유는 없는것 같았습니다.
 
그 근거로는 tomcat에서 사용하는 스레드 사이즈가 20개 정도라는걸 기억하고 있었고 실제 회사에서도 여러번 요청해도 문제가 없었습니다. 
왠지 다른 쪽 문제인것같아서 이것 저것 확인하다보니 아래코드를 집어넣으면 해결된다는 사실을 알게되었습니다.

 entityManager.close();

코드를 입력하지않아서 entitymager가 종료되지 않아 스레드가 일처리를 끝내고 있지않는 상태여서 커넥션 풀링야만 제대로 돌아갔습니다.
 

 
결론은 connection pooling을 사용하지 않았고 entityManager.close();가 되지 않아서 문제가 되었던 헤픈닝이었습니다.
pooling-size 2개로도 충분히 돌아간다는 사실을 알게되었습니다.
 
참고링크:
https://techblog.woowahan.com/2664/

+ Recent posts