제 생각과 docs 그리고 다른 분들의 생각 등을 참고하여 작성한 글입니다. 정답이 아닐 수 있으므로 잘못된 부분은 댓글 또는 메일 부탁드립니다!

Async를 이용하여 EventListener 사용하기

이전 포스팅에서 트랜잭션을 주의하여 비동기 처리하는 방법에 대해 알아봤습니다. 이번에는 해당 방법을 적용했을 때의 문제점을 고민해봤습니다. 우선, 서비스 로직에 비동기 메서드가 존재하기 때문에 의도하지 않은 다른 곳에서 비동기 메서드를 실수로 사용할 수도 있겠다는 생각을 하게 됐습니다. 비동기 처리에는 앞선 포스팅에서 설명드린 것처럼 트랜잭션 문제를 야기할 수 있기 때문에 실수로 사용하지 않기 위해서 똑같은 메서드를 구현해주어야 하는 불편함도 있습니다. 그래서, 여러 메서드에 각각 비동기 처리를 해주는 대신, 하나의 메서드에서 비동기로 처리할 각 함수를 호출하고 이를 비동기 처리하면 좋겠다는 생각을 했습니다. 또한, 게시판을 삭제하기 위해서 게시글과 댓글, 좋아요 등을 삭제하는 추가적인 로직을 수행해야 ..

Spring 2022.03.16 2

Transaction을 주의하여 Async 사용하기

이번에 프로젝트 구현하면서 비동기 처리에 대해 필요성을 느끼게 됐습니다. 사용할 때 발생했던 문제점에 대해서 이야기해보려고 합니다. 게시판과 게시글, 댓글의 연관 관계 Board와 Post, Comment를 삭제하는 로직을 예제로 이야기해 보겠습니다. 실제 엔티티들의 데이터 관계 Board를 삭제하면 Post와 Comment도 삭제되어야 하기 때문에 아래와 같은 로직을 작성하게 됐습니다. Board 삭제 시, Post와 Comment 삭제 연쇄 작용 로직 (동기적 처리) 위의 코드를 실행하면, Board를 삭제할 때 Post와 Comment 삭제 시간도 포함하여 대기해야 합니다. 게시판의 데이터가 많다고 가정하면, 응답 시간이 길어지게 되는 상황이 발생하게 됩니다. 당장 Board 하나를 삭제하는 응답이..

Spring 2022.02.20 1

Facade Layer 도입하게 된 이유

이번에 게시물 서비스를 구현하면서 두 번의 시행착오를 겪고 퍼사드 레이어를 도입하게 됐습니다. 어떤 이유인지 예제 코드로 문제점을 확인하여 설명하겠습니다. 회원과 게시판, 게시글의 연관 관계 위처럼 Post를 생성할 때는 Member의 정보와 Board의 정보가 필요합니다. 이것을 고려하여 Post를 생성해 보겠습니다. Repository를 주입하여 Post 생성하기 PostService에서 다른 도메인의 레포지토리를 주입하여 구현했습니다. 이것은 PostService의 역할과 책임을 적절하게 나누지 못한 케이스입니다. 결국에 위의 코드처럼 레포지토리를 주입하는 곳마다 똑같은 로직을 구현해야 하는 문제가 발생하게 됩니다. 그래서 각 도메인의 레포지토리는 각 서비스에서 구현해야 합니다. 그렇다면, Post..

Spring 2022.02.16 3

통합 테스트와 단위 테스트

글에서 나오는 예제의 구현 코드와 테스트 코드는 해당 링크에 있습니다. 이번에 팀 내에서 테스트 코드를 어떤 방법으로 작성하면 좋을지 고민하던 중, TDD와 BDD에 대해 다시 공부하게 됐습니다. TDD와 BDD 외에도 DDD, ATDD 등 수많은 xDD가 존재합니다. xDD는 모두 소프트웨어 개발 방법론입니다. x주도 개발이라고 해서, 어느 것을 중점으로 두고 개발을 진행할지 미리 정해 두는 것입니다. 저는 그중에서도 TDD와 BDD 그리고 테스트 코드에 대해 고민해 봤습니다. TDD 사진 출처 TDD는 테스트 주도 개발이라는 뜻입니다. 요구사항이 주어지면, 요구사항에 대한 에러를 고민하고 바로 에러에 대한 테스트 코드를 작성한 후, 해당 테스트를 통과하도록 구현 코드를 작성하는 개발 방법론입니다. 예..

Spring 2022.07.28 0

Spring batch BadSqlGrammarException

Description 스프링 배치를 처음 실행하려고 하면 BadSqlGrammarException 에러가 발생하는 현상이 있습니다. Error message java.lang.IllegalStateException: Failed to execute ApplicationRunner ... ... ... Caused by: org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?]; nested exception is java.sql.SQ..

Spring 2022.06.21 0

Slack으로 에러 알림 받기

현재 제가 담당하고 있는 팀 프로젝트에서 발생하는 에러를 효과적으로 처리하고, 팀원들이 이를 실시간으로 확인할 수 있도록 개선하고자 합니다. 간단하게 Slack webhook API를 활용하여 이를 해결해보려고 합니다. Slack webhook URL 생성하기 구현하기 전에 이미 slack workspace가 있다고 가정하고 설명하도록 하겠습니다. slack webhook을 생성하기 위해서는 아래와 같이 https://api.slack.com/apps 페이지에 접속해야 합니다. webhook를 생성하기 위해서는 app을 생성해야 합니다. “Create New App”를 클릭합니다. “From scratch”를 클릭합니다. 그리고 생성할 “App Name”을 적어줍니다. 이는 알람을 보내는 주체가 됩니다...

Spring 2023.06.01 4

Linux Terminal Backspace Issue

Description 리눅스 터미널에서 Backspace 키가 공백이나 제어 문자 (^H 또는 ^?)로 인식되는 경우에 해결 방법을 제시하겠습니다. Solution export TERM=vt100 Conclusion 이런 경우는 일반적으로 터미널 설정과 관련이 있습니다. 터미널은 환경 변수인 TERM을 사용하여 터미널의 유형을 식별합니다. TERM 변수는 터미널이 어떤 기능과 동작을 지원하는지에 대한 정보를 제공합니다. "export TERM=vt100" 명령은 TERM 환경 변수를 "vt100"으로 설정하는 것을 의미합니다. vt100은 오래된 터미널 유형 중 하나로, 대부분의 터미널에서 동작하는 터미널 에뮬레이터입니다. vt100으로 설정하면 백스페이스 키를 올바르게 인식할 수 있습니다. Refere..

Etc 2023.05.31 0

Fixture monkey

Fixture 테스트를 수행하는 데 필요한 정보나 오브젝트를 말한다. Fixture monkey 테스트 수행에 필요한 픽스쳐를 간편하게 바인딩해주고 랜덤한 값을 넣어줄 수 있도록 하는 라이브러리입니다. given 단계가 길어지면서 코드의 가독성을 떨어뜨린다고 느껴져서 이를 도입하게 되었습니다. 예제를 통해서 이를 적용해 보겠습니다. 리팩토링 전 리팩토링 후 이처럼 픽스쳐 몽키를 사용합니다. 픽스쳐 몽키를 사용하면서 여러 가지 장점을 느꼈는데, 개인적으로 제가 좋다고 느낀 것을 말씀드리겠습니다. 랜덤한 값 바인딩 픽스쳐 몽키는 랜덤한 값을 바인딩해주며, 랜덤 설정 또한 어떻게 랜덤하게 할 건지 정의해줄 수 있습니다. 랜덤 값의 바인딩 기능은 테스트를 실행할 때마다 새로운 값들이 바인딩됨으로써 코드의 신뢰성..

Spring 2022.03.18 0

java.lang.UnsupportedOperationException

서론 java.lang.UnsupportedOperationException은 특정 연산이나 기능이 현재의 상황에서 지원되지 않을 때 발생하는 예외입니다. 이 예외는 주로 불변 객체나 수정이 불가능한 상태의 컬렉션에서 발생하며, 이에 대한 적절한 처리가 필요합니다. 이 예외가 발생하는 두 가지 예제를 통해 어떻게 해결할 수 있는지에 대해 설명하겠습니다. Arrays.asList()로 생성된 고정 크기 리스트에 원소 추가 Collections.singletonList()로 생성된 리스트에 원소 추가 결론 이처럼 불변 컬렉션으로 선언된 객체에 대해서 가변 하게 사용하면, java.lang.UnsupportedOperationException가 발생할 수 있습니다. 아래 코드는 올바른 예제입니다. 이상입니다...

Java 2023.12.28 0

Adapter pattern

Adapter pattern 사진 출처 어댑터 패턴은 서로 호환되지 않는 두 인터페이스를 사용할 수 있도록 해줍니다. 클래스의 인터페이스를 클라이언트가 원하는 다른 인터페이스로 변환합니다. 인터페이스를 사용자가 기대하는 다른 인터페이스로 변환하는 패턴으로, 호환성이 없는 인터페이스 때문에 함께 동작할 수 없는 클래스들이 함께 작동하도록 해줍니다. 쉽게 말해서, 메모리 카드에 사진이 몇 개 있고 이를 컴퓨터로 전송해야 한다고 생각해보겠습니다. 그것들을 전송하려면 메모리 카드를 컴퓨터에 연결할 수 있도록 컴퓨터 포트와 호환되는 일종의 어댑터가 필요합니다. 이 경우 카드 리더는 어댑터입니다. 또 다른 예로는 유명한 전원 어댑터가 있습니다. 세 다리 플러그는 두 갈래 콘센트에 연결할 수 없으며 두 갈래 콘센트와..

Spring 2022.06.29 0

슬라이스 테스트를 하게 된 이유

테스트하는 이유 개발자라면 때때로 기능을 구현하고 나서 실행을 했을 때, 에러가 발생할 때가 있을 겁니다. 에러를 잡는데 짧은 시간이 걸릴 때도 있지만, 오랜 시간이 걸리기도 합니다. 특히, 저 같은 초급 개발자라면 경험이 부족하기 때문에 더욱 오래 걸릴 거라고 생각합니다. 에러를 잡는데 오랜 시간이 걸린 적이 많았고, 정말 사소하고 간단한 부분을 잘못해서 발생한 문제를 오랜 시간 동안 고민하여 해결한 적도 있습니다. 테스트 코드를 짜는 이유는 많지만, 저는 이러한 점을 해결하기 위해서 테스트 코드가 꼭 필요하다고 생각했습니다. 본인이 새롭게 작성한 코드마다 테스트를 진행하게 된다면, 적어도 기능이 완성됐을 때의 에러가 나의 코드로 인한 문제가 아닌 설정 등과 같은 외부 요인에서 발생한 문제라는 것을 알..

Spring 2022.03.18 0