지난 프로젝트에서 과업으로 레거시 프로젝트의 프로시저를 Java의 비즈니스 로직으로 전환하는 과업이 있었다.
현업에선 프로시저의 사용에 대해 뜨거운 감자처럼 찬반이 갈리는 분위기가 좀 있는 분위기다.
“프로시저 안좋다” “유지보수 힘들다” “요새 읽을 수 있는 개발자가 별로없다” 등의 반대측의 여러 이유를 듣긴 했지만,
정말 왜 현업 백엔드에서는 프로시저를 선호하지 않을까? 개념과 장단점을 알아보기로 한다.
Stored Procedure란
저장 프로시저
또는 스토어드 프로시저
는 일련의 쿼리를 마치 하나의 함수처럼 실행하기 위한 쿼리의 집합이다. 데이터베이스의 작업의 절차를 RDBMS에 저장한 것이다.
프로시저
를 이해하기 앞서 애플리케이션의 아키텍처에 대한 간략히 정리해보자.
일반적인 애플리케이션의 아키텍처는 레이어드 아키텍처 를 따른다.
레이어드 아키텍처의 각 계층은 각각 아래와 같은 특징을 가진다.
✔️ Presenataion Layer : 클라이언트와 시스템이 연결되는 부분.
✔️ Business Layer : 비즈니스 로직을 구현하는 부분. 실제 시스템이 구현해야 하는 핵심 로직이 담긴다.
Presentation Layer
로부터 Request와 Parameter를 받아 처리하는 부분
✔️ Persistence Layer : 데이터의 영구 저장과 관리를 담당하는 부분. 웹 애플리케이션과 상호작용하며 데이터베이스와의 상호작용을 추상화한다.
✔️ Database Layer : 실제 데이터가 저장되는 물리 데이터베이스 부분.
여기서 프로시저
는 Business Layer가 아닌 Database Layer에서 로직을 처리하게 된다.
🚩장점
- 하나의
request
로 여러 SQL문을 실행 할 수 있다. (네트워크 부하 감소) - 데이터베이스 레벨에서 로직을 처리하여 처리시간이 짧다
- 데이터베이스의
Trigger
와 결한하여참조무결성
유지가 가능하게 된다. 즉, 응용 프로그램의 로직을 거치지 않고도 데이터의 유지가 가능해진다 - 구체적인 하나의 Task를 수행할 수 있다.
- 로직이 변경되어도 애플리케이션의 수정, WAS 등의 배포 작업 없이 프로시저의 수정만으로 로직 수정이 가능하다.
🚩단점
- 유지보수의 비용이 크다
- 비즈니스 로직이
비즈니스레이어
와데이터레이어
에 흩어져 있어 로직파악에 시간과 버전관리도 2배의 비용이 소요된다. - 서비스 이용량 트래픽 증가에 따라 CPU 사용량이 늘어나 자원 증설할 경우, DB서버 증설보다 WEB/WAS 증설이 용이하다.
- 비즈니스 로직이
디버깅
이 불가능하고 개발자들이 프로시저 문법도 알아야하며 개발의 업무 효율성이 낮다.- 로직의 라인수가 급진적으로 증가할 수 있어 가독성이 떨어지고 유지보수성이 낮다.
- 비즈니스 로직의 일부로 사용하는 경우 업무의 사양 변경시 프로시저의 정의를 변경해야 한다. 이때 불필요한 작업과 변경에 의한 실수, 그에 따른 장애를 발생시킬 가능성이 있다.
실무 백엔드에서는 왜 프로시저를 선호하지 않을까?
프로시저를 사용했을때 단점에서 정리한 것과 실제 업무단에서 느껴지는 디버깅과 장애 발생 가능성의 단점과 최근 애플리케이션 중심의 설계, MSA 아키텍처와 같은 트렌드에서 가급적 배제하는 것이 이상적이라는 결론으로 테크기술을 선도하는 기업들에서는 대체로 백엔드에서 프로시저 사용을 `지양`하고 있다고 보여진다.
그러나 내가 참여했던 지난 프로젝트에서 무려 2023년임에도 프로시저를 쓰고 있었다는 것을 보면, 아직도 현에서 어쩌면 거대 레거시 시스템에서 현재 잘 돌아가고 있는것을 전환했을 때 발생할 수 있는 리스크와 비즈니스 로직으로 전환에 드는 자원(인력, 시간, 비용 등)에 대한 부담에 있어 유지를 하는 것 같다.
결론은 "좋고 나쁘다" 인 것보다는 그냥 프로젝트의 상황과 스펙에 따라 적당한 기술을 채택할 뿐! 🙏🏻
[참조]
- Strored Procedure의 단상
- 프로시저에 업무로직(비지니스로직)을 넣으면 안되는 이유
- 웹 애플리케이션 서버를 위한 PL/SQL 프로그래밍-사례 분석을 통한 PL/SQL의 이해
'Database' 카테고리의 다른 글
[PostgresQL] 드디어 나온 PostgresQL 15의 Merge into 구문 사용하기 (0) | 2024.08.19 |
---|---|
날짜 타입, Timestamp와 Datetime의 차이 알아보기 (0) | 2021.12.27 |
[PostgresQL] 중복데이터 제거하고 하나만 남기기 (1) | 2021.11.28 |
[PostgreSQL] Returning 문법으로 Row 정보 리턴 받기 (0) | 2021.11.23 |
[PotsgresQL] 이 없으면 잇몸으로! MERGE 대신 UPSERT 사용하기 (0) | 2021.11.23 |