전체 글

.
상황에 따른 Hikari CP의 커넥션 풀 상태가 궁금해졌습니다.@Transactional 어노테이션에 따라 active 가 되고 언제 다시 idle로 돌아가는지 알아보기 위해 모니터링을 위한 준비를 했습니다.다음과 같은 클래스 구조에서 확인해 보겠습니다.다음과 같이 테스트 합니다.1. 먼저 facade 클래스의 메서드가 실행되면 Thread.sleep으로 많은 일을 처리했다고 가정합니다.2. @Transactional 어노테이션이 걸려있는 서비스의 메서드를 호출합니다. 각 과정 사이에 HikariCP 로그를 찍어 Connection pool 상태를 확인합니다.자세한 소스코드는 다음 github를 참고해 주세요. 먼저 HikariCP를 모니터링하기 위해 application.yml 에 다음 설정을 추가합..
같은 팀원의 코드리뷰 중 JPA 변경감지를 사용하지 않고 명시적으로 saveAll 메서드를 호출하고 있는 코드를 발견하였습니다.변경감지를 사용하여 처리하는 게 어떻겠냐고 제안하였고 팀원 분께서는 변경감지가 동작하지 않는다고 하였습니다.메서드에는 @Transactional 어노테이션이 걸려있었고 트랜잭션 커밋 시 영속성 컨텍스트가 flush 되기 때문에 저는 동작할 것이라고 예상했는데 말이죠. 팀원 분께 괜찮다면 제가 한 번 실행해 봐도 되냐고 여쭤본 후 실행해 보니 정말 변경감지가 동작하지 않았습니다!🫨계속 확인해 보다가 이상한 점을 발견했습니다.팀원 분이 작성하신 코드는 다음과 같은 구조를 가지고 있었습니다.@Servicepublic class SelfInvocation { public Stri..
@Trasactional 어노테이션의 propagation에 대해 알아보고 중첩된 트랜잭션을 사용하게 될 때 생기는 문제에 대해 알아보겠습니다. @Transactional 어노테이션의 propagation 속성에는 총 7가지의 속성이 있습니다. public enum Propagation { REQUIRED(0), SUPPORTS(1), MANDATORY(2), REQUIRES_NEW(3), NOT_SUPPORTED(4), NEVER(5), NESTED(6); private final int value; private Propagation(int value) { this.value = value; } public int value() { return this.value; } } Propagtaion 속성 ..
본 글은 클린코드 6장을 읽고 난 후 개인적인 생각입니다. 자료 추상화 변수를 비공개로 정의하는 이유는 변수에 의존하지 않게 만들기 위해서입니다. 하지만 수많은 프로그래머가 getter 혹은 setter 함수를 당연하게 공개해 비공개 변수를 외부에 노출합니다. 변수를 private으로 선언하더라도 각 값마다 getter 함수와 setter 함수로 제공한다면 구현을 외부로 노출하는 셈입니다. 이렇게 자료를 세세하게 공개하기보다는 추상적인 개념의 함수를 만드는 것이 좋다고 합니다. 저는 setter에 대해서는 이 내용에 동의하지만 getter까지 전부 추상적인 개념(클래스 내부의 어떤 비공개 인스턴스 변수를 가져오는지 모르도록 추상화)으로 일일이 변경해야 한다는 부분에서는 클래스 용도마다 차이가 있을 것으로..
스프링부트 3.x부터 Spring cloud sleuth로 트레이싱 기능을 추가할 수 없게 되었습니다. 마이그레이션 가이드 https://github.com/micrometer-metrics/tracing/wiki/Spring-Cloud-Sleuth-3.1-Migration-Guide Spring Cloud Sleuth 3.1 Migration Guide Provides tracing abstractions over tracers and tracing system reporters. - micrometer-metrics/tracing github.com 앞으로는 Micrometer 의 brave 의존성을 추가해 트레이싱 기능을 사용할 수 있습니다. 적용해 볼 환경은 아래와 같습니다. Spring boo..
본 글은 클린코드 5장을 읽고 난 후 주관적인 생각입니다. "은 탄환은 없다"라는 말처럼 항상 상황에 맞춰 생각을 한 번 더 하는 습관이 중요한 것 같습니다. 형식을 맞추는 목적 오랜 시간이 지나도 맨 처음 잡아놓은 구현 스타일과 가독성 수준은 유지보수 용이성과 확장성에 계속해서 영향을 미칩니다. 때문에 너무 엄격하지 않은 어느정도 스타일과 규율은 필요하다고 생각합니다. 적절한 행 길이를 유지하라 대부분 500줄을 넘지않고 200줄 정도인 파일로도 커다란 시스템을 구축할 수 있다고 합니다. 개인적인 생각으로는 파일의 길이가 길어지는 건 하나의 클래스가 너무 많은 일을 하고 있을 때 그렇다고 생각합니다. 예를 들어 주문이라는 큰 상위개념이 있고 하위개념으로는 옵션, 가격, 주문상품 등이 있다고 했을 때 주..
어찌하다 보니 Gitlab repository에서 약 30여 개 프로젝트를 Github 리파지토리로 마이그레이션 하는 경우가 생겼습니다. 일단은 기존 저장소를 복제합니다. git clone --bare {복제할 저장소주소} 그 후 복제한 저장소의 폴더로 접근해 cd {복제할 저장소주소} 새로 옮길 저장소로 이동시킵니다. git push --mirror {옮길 저장소주소} 이렇게 여러 개의 리파지토리를 옮기는 쉘 스크립트를 작성한 후 실행 시킬 수 있습니다. * 한 번 clone 하여 push 하면 그 이후에 재실행하면 변경된 부분만 push 할 수 있습니다. 이렇게 옮기는 와중에 특정 몇몇 리파지토리가 push 할 때 다음과 같은 오류메시지와 함께 push 가 되지 않았습니다. [remote reject..
코드리뷰를 하던 중 동료 개발자 분 코드에서 1건 저장 행위만 하는 Service 레이어 메서드의 @Transactional 이 없는 것을 발견했습니다. 나: "어? 이게 있어야하지 않을까요?" 동료 개발자 : "1개 만 저장하는 건데 있어야 하나요?" 생각해 보니 딱히 이유를 찾지 못했습니다. 어차피 spring-data-jpa 구현체인 SimpleJpaRepository의 save 메서드에서 @Transactional 이 걸려있습니다. 분명 제가 본 강의에서는 서비스 레이어의 클래스에는 @Transactional(readOnly=true) 어노테이션을 붙이고 쓰기 메서드에는 @Transactional을 붙이는 방식을 많이 활용한다고 했는데 이유가 기억나지 않았습니다. 조금 더 검색해 본 결과 다음과 ..
flutter로 firebase , google_sign_in를 이용하여 구글로그인 구현 시 IOS에서는 문제가 없으나 AOS에서만 idToken 이 null로 응답되는 문제가 발생하였습니다. @override Future authorize() async { final googleUser = await GoogleSignIn().signIn(); final googleAuth = await googleUser?.authentication; return googleAuth?.idToken ?? ""; } flutter google_sign_in 라이브러리를 통해 개발하게 되면 authentication을 통해 idToken을 얻어올 수 있는데 해당 값으로 서버에서 유효한 토큰인지 체크합니다. 하지만 안드로..
글을 읽기 전에 앞 서 모든 connection reset 오류 메시지 해결책에 대해 해당하지 않습니다. 여러 가지 오류가 있는 것으로 알고 있습니다. stack trace를 잘 살펴보면 더 세밀한 정보를 얻을 수 있습니다. 문제발생 SOAP 관련한 통신을 JAXWS 라이브러리를 통해 사용하고 있었습니다. SOAP 관련 통신 플랫폼 자체를 변경하게 되어 스프링부트 3.x로 버전을 올리고 관련 라이브러리 들도 전부 버전을 올리게 되었는데 간헐적으로 Could not send message. 라는 오류 메시지와 함께 SOAP 요청이 목적지 API에 전달되지 않는 오류가 발생하였습니다. 메시지 내용을 자세히 파악해보니? connection reset 이라는 오류 메시지도 있습니다. 좀 더 파보니 Connec..
infitry
디벨뤼팽