거래(transaction) 버그를 배포한 뒤, linter를 만들었다
핵심 내용
Go 트랜잭션 경계를 벗어나는 DB 호출을 잡는 custom linter 제작기.
자세히 보기
트랜잭션 경계 밖으로 새는 DB 호출 때문에 운영 장애를 겪은 뒤, 컴파일 시점에 잡는 Go용 custom linter를 만들었다.
핵심 버그는 Transaction 콜백 안에서 tx 대신 s.repo 같은 외부 repository를 실수로 사용하는 것이다. 코드는 정상적으로 컴파일되고 테스트도 통과하지만, 실제로는 일부 DB 작업이 트랜잭션 밖에서 실행돼 데이터 손상이나 race condition으로 이어질 수 있다.
이를 잡기 위해 Go의 go/analysis 프레임워크를 사용했다. analysis.Analyzer를 만들고, inspect.Analyzer로 AST를 효율적으로 순회하면서 Transaction 호출을 찾는다. 이후 콜백 내부를 분석해 다음을 검사한다.
- repo 메서드 호출이 transaction parameter가 아닌 외부 repository를 쓰는지
- 함수 인자 전달 시 transaction repository가 아닌 외부 repository를 넘기는지
- 헬퍼 함수 체인까지 재귀적으로 따라가며, 여러 단계를 거친 간접 위반도 잡는지
트랜잭션 parameter는 단순 이름 비교가 아니라 types.Object를 비교해 추적한다. 그래서 변수명이 shadowing되어도 동일한 식별자인지 정확히 판별할 수 있다.
또한 중첩 Transaction 호출은 별도 스코프로 취급해 현재 분석에서 멈추고, visited function 집합으로 무한 재귀를 막는다.
마지막으로 analysistest로 테스트를 구성해, 정상 코드와 위반 사례를 함께 검증하는 흐름까지 정리한다. 전체적으로 이 글은 Go AST 분석으로 실무 버그 패턴을 정적 검출하는 방법을 구체적으로 보여준다.
이 한국어 요약은 AI가 자동으로 만들었습니다. 원문의 주장과 맥락은 원문에서 확인해 주세요. 저작권은 원저작자에게 있습니다.