회사 코드 중에 알림톡을 발송하는 로직이 있었고 로직은 다음과 같이 구현이 되어 있었습니다.
- 비즈니스 로직을 수행
- 알림톡 이벤트 발행
- 알림톡 이벤트 소비
- 알림톡 발송
이벤트를 발행할 때는 다음과 같이 비즈니스 로직에서 수행된 결과값 중 하나를 사용하고 있었습니다.
이를 컬럼 'happyCallId' 라고 하겠습니다.
아래는 이벤트 발행에 사용되는 JSON 객체입니다.
{
"happyCallId" : 1234567 [Long 타입]
...
}
id의 값의 정상적인 범위는 2_000_000 ~ 2_500_000 범위 값이 되어야 합니다.
하지만 간헐적으로 알림톡에 발행될 때 입력되는 id 값이 17_000_000 ~ 18_000_000 범위 값인 경우가 있었습니다.
여러가지 로그를 찍으며 의심되는 범위를 좁혀갔고 이상한 코드를 발견하게 되었습니다.
특정 조건에 따라 해피콜 로그 데이터를 생성하는 쿼리인데 다음과 같습니다.
<insert id="..." parameterType="HappyCall" useGeneratedKeys="true" keyProperty="srl" keyColumn="srl">
INSERT INTO happy_call_log (...) values (...)
</insert>
useGeneratedKeys, keyProperty, keyColumn은 생성된 쿼리의 결과를 이용하여 key 값을 매핑해줄 때 사용하는 설정입니다.
자세한 설명은 아래와 같습니다.
useGeneratedKeys
- 데이터베이스에서 자동으로 생성되는 키 값(예: Auto Increment ID, 시퀀스 값)을 MyBatis가 자동으로 가져오게 하는 옵션
keyProperty
- 자동으로 생성된 키 값을 매핑할 Java 객체의 필드를 지정하며, MyBatis는 이 필드에 데이터베이스에서 반환된 키 값을 저장합니다.
keyColumn
- 데이터베이스에서 자동 생성된 키 값이 저장되는 컬럼 이름을 지정하며, 주로 키 값이 여러 컬럼에서 생성되는 경우나, 데이터베이스의 키 생성 컬럼이 명시적으로 필요할 때 사용됩니다.
위의 쿼리는 happy_call_log의 로우 데이터가 생성되면 srl 컬럼의 값을 입력된 파라미터 객체에 srl 필드에 매핑시켜버립니다.
알림톡 발송 이벤트 발송 전 비즈니스 로직이 수행될 때, 위의 쿼리에서 사용되는 happyCall 객체의 srl이 불변이라는 가정으로 로직이 구현되어 있었습니다. 하지만 쿼리가 실행되고 나서 happy_call_log의 srl로 매핑되어 쓰이다 보니 알림톡에서 예상치 못한 예외가 지속적으로 발송하였습니다.
불필요한 useGeneratedKeys, keyProperty, keyColumn 설정을 제거하였고 이를 통해 문제를 해결하였습니다.
레거시 코드를 다루다 보면 의도를 알 수 없는 코드들이 많이 보여 주의가 필요합니다.
'[개발] 프레임워크 > Spring' 카테고리의 다른 글
build.gradle 파일 문법에 대해서 알아보자. (1) | 2024.10.22 |
---|---|
Spring에서 SSE(Server-Sent Event) 구현하기 (2) | 2024.09.08 |
Postman에서 카카오 OAuth AccessToken 발급 받기 (0) | 2024.09.08 |
Security 설정으로 static 파일 허용 (0) | 2024.08.20 |
Spring Retry (0) | 2024.08.11 |