어느 날 데드락이 찾아왔다.
·
데이터베이스
문제상황한끼족보 서비스는 유저 피드백을 바탕으로 2차 MVP 때, 메뉴를 등록하고 수정 및 삭제할 수 있는 기능을 도입하기로 했다. 해당 플로우를 스프린트 기간 내에 열심히 구현해서 성공적으로 배포까지 완료했다. 이렇게 서비스를 배포하기 직전, 기획 팀원들이 QA를 진행하는 도중에 에러가 발생했다는 연락을 받게 되었다. 로그를 확인해본 결과 DB단에서 발생한 에러였고 원인을 분석하기 위에 MySQL에 접속해 show engine innodb status; 명령어를 통해 로그를 확인한 결과, 데드락이 발생했다는 로그를 발견하게 되었다. 이번 글에서는 왜 데드락이 발생했는지, 어떻게 해결했는지 살펴보고자 한다.실제 로그 로직 흐름테이블 구조현재 한끼족보의 데이터베이스 구조는 다음과 같다. 하나의 식당에 여러..
[Programmers] 파괴되지 않은 건물 (Java) - 2022 KAKAO BLIND RECRUITMENT
·
자료구조&알고리즘
문제 링크https://school.programmers.co.kr/learn/courses/30/lessons/92344 프로그래머스SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프programmers.co.kr 효율성 테스트 실패 코드효율성을 고려하지 않고 Brute Force 방식으로 코드를 작성한다면, 굉장히 쉬운 문제다.class Solution { public int solution(int[][] board, int[][] skill) { for (int[] s : skill) { if (s[0] == 1) { // 공격 for (int i=s[1]; i 0) { ..
삼성 SDS 알고리즘 특강 후기
·
끄적끄적
지원한 이유이번 상반기에 진행했던 삼성SDS에서 주관하는 대학생 알고리즘 특강에 참여했다. 평소 알고리즘 공부를 소홀히 한 탓인지 항상 코딩테스트에서 좌절했었다. 혼자서 알고리즘을 준비하니 뭔가 체계가 안잡히는 느낌이 들었고 운이 좋게도 학교 에타에서 해당 공고을 발견하게 되어 망설임 없이 바로 지원하였다.합격자는 오롯이 지원서를 통해서만 선발된다. 개인적인 생각이지만, 지원서에 내가 이 특강이 필요한 이유를 진실되게 적는다면 무난히 선발되지 않을까 싶다. 또한, 재학 중인 학교와 학점 증명서를 제출해야 하기 때문에 학점 관리를 잘해놓는 것을 추천한다.참고로 특강은 C++과 Java로만 진행되며 Pro 시험 또한 2개의 언어로만 응시가 가능하기 때문에 파이썬을 이용해서 코테를 연습한 사람이라면 지원을 한..
로그인 코드 리팩토링 대장정
·
Spring
미뤄두고 미뤄두던 로그인 로직 리팩토링.. 더이상 미룰 수 없다고 생각해서 이번에 코드를 새롭게 갈아엎어보았다. 그 과정을 살펴보자!기존 코드의 문제점 🤔SOLID 원칙 위반기존 코드의 가장 큰 문제점은 객체지향스럽지 못하다는 것이다.위의 코드는 AuthService의 코드 중 일부로 외부 네트워크와 통신하여 사용자의 정보를 받아오고 또 탈퇴하는 코드이다. 인자인 platform은 사용자가 가입을 할 때, 클라이언트에서 어느 플랫폼으로 가입을 시도했는지 서버에게 보내준 enum 값이다. 이 코드의 문제점은 무엇일까? DIP와 OCP에 위배된다는 점이다. 만약, 기획의 요구사항의 변경으로 구글 로그인이 추가되었다면 어떨까? 구글 서버와 통신하기 위한 로직과 클래스를 생성해야하는 것은 물론이고, 이 Aut..
스프링 트랜잭션과 전파
·
Spring
문제점을 찾아보자!위 코드는 '한끼족보'에서 로그인을 담당하는 코드이다. 무엇이 문제일까?트랜잭션 범위RealMySQL에서는 트랜잭션의 범위를 최소화 하라는 조언이 있다. 특히, 외부 서버와 통신을 하는 과정은 트랜잭션 내에서 제거하는 것이 좋다고 한다. 프로그램이 실행되는 동안, 외부 서버와 통신할 수 없는 상황이 발생한다면 웹 서버 뿐만 아니라 DBMS 서버까지 위험해지는 상황이 발생할 수 있기 때문이다.다시 돌아와서, 코드를 살펴보자. 무엇이 문제일까?위 로직은, DB에 유저를 조회하거나 저장하는 로직과 함께 애플과 카카오 서버를 통해 사용자의 정보를 가져오는 getSocialInfo메서드 즉, 외부 서버와 통신하는 로직이 하나의 트랜잭션 단위로 묶여져있다. 만약, 카카오 서버에 문제가 생긴다면 어..
[Spring] 스프링 DB 2편 - 섹션 10~11
·
Spring
외부 트랜잭션과 내부 트랜잭션트랜잭션 전파란, 이미 진행 중인 트랜잭션이 존재할 때 추가로 트랜잭션을 수행하려는 상황에서 어떻게 동작할 지 결정하는 것을 트랜잭션 전파(propagation)이라고 한다. 트랜잭션 전파에는 여러가지 옵션이 존재하지만, 기본 옵션이 REQUIRED를 기준으로 설명하겠다.외부 트랜잭션이란 쉽게 말해서 가장 먼저 시작된 트랜잭션이다. 그리고 내부 트랜잭션은 그 이후에 호출된 트랜잭션으로 외부에 트랜잭션이 수행되고 있는 도중에 호출되기 때문에 마치 내부에 있는 것처럼 보여서 내부 트랜잭션이라 한다.흐름내부 트랜잭션을 시작하는 시점에는 이미 외부 트랜잭션이 진행중인 상태이다. 이 경우 내부 트랜잭션은 외부 트랜잭션에 참여한다. 즉, 내부 트랜잭션은 외부 트랜잭션을 기대로 이어 받아..
[Spring] 스프링 DB 2편 - 섹션 9
·
Spring
선언적 트랜잭션과 AOP@Transactional이라는 애노테이션을 사용하여 매우 편리하게 트랜잭션을 적용하는 것을 선언적 트랜잭션 관리라고 한다. 이 방식은 기본적으로 프록시 방식의 AOP가 적용된다.AOP의 핵심은, 실제 객체 대신 트랜잭션을 처리해주는 프록시 객체가 스프링 빈에 등록된다는 것이다. 또한 주입을 받을 때도 실제 객체 대신에 프록시 객체가 주입된다. 즉, 선언적 트랜잭션을 사용하면 항상 프록시를 통해서 대상 객체를 호출한다는 것이다.프록시 내부 호출만약, 프록시를 거치지 않고 대상 객체를 직접 호출하게 되면 어떻게 될까? 2가지 상황에 대해 알아보자.상황 1트랜잭션이 적용된 Internal() 메서드가 내부 호출로 External() 메서드를 호출하는 상황이다. Internal() 메서..
[한끼족보] 인덱스를 활용한 조회 속도 개선기
·
데이터베이스
문제 상황한끼족보에서는 사용자가 마음에 드는 식당을 ‘좋아요’로 저장하고, 이후 좋아요한 식당 목록을 조회할 수 있다. 기존에는 전체 목록을 한 번에 내려주는 방식이었지만, 커서 기반 페이지네이션을 도입해 응답 시간을 개선했고 그 과정은 이전 글에 정리했다. 이번 글에서는 페이지네이션을 넘어 더 빠른 응답을 얻기 위해 실행 계획을 분석하고, 그 결과를 바탕으로 쿼리를 튜닝한 과정을 공유하고자 한다.실행 계획을 분석해보자.개발 환경 데이터베이스에서 식당 정보 10만개를 삽입하고 각 유저가 적어도 25개의 식당에 대해 좋아요를 눌렀다고 가정하고 테스트 환경을 구성한 뒤, 쿼리 실행계획을 확인해보았을 때, 다음과 같은 실행계획을 확인할 수 있었다.SELECT s.*FROM heart hJOIN store s ..
동시성 문제를 해결해보자
·
Spring
한끼족보에서 발생하는 동시성 문제'한끼족보'에도 동시성 문제(=Race Condition)가 존재한다. 예를 들어 2명의 유저가 동시에 하나의 가게에 좋아요를 누른다면, 해당 가게의 전체 좋아요 수가 2가 아니라 1로 집계되는 문제가 발생했다. 왜 이런 문제가 발생하는 것일까?문제 발생 원인위는 현재 '한끼족보'의 테이블 구조이다. '좋아요 수'를 비정규화 하여 가게 테이블에 위치해 있는 상태이다.@Transactionalpublic HeartCreateResponse createHeart(final HeartPostCommand heartPostCommand) { User user = userFinder.getUserReference(heartPostCommand.userId()); ..
[Spring] 스프링 DB 1편 - 섹션 3~4
·
Spring
트랜잭션트랜잭션은 작업의 완전성을 보장해 준다. 즉, 논리적인 작업 셋을 모두 완벽하게 처리하거나, 처리하지 못할 경우에는 원 상태로 복구하여 작업의 일부만 적용되는 현상(Partial update)이 발생하지 않도록 해준다.ACID원자성(Atomicity)트랜잭션 내에서 실행한 작업들은 모두 성공하거나 모두 실패해야 한다.일관성(Consistency)모든 트랜잭션은 일관성 있는 데이터베이스 상태를 유지해야 한다. 예를 들어 데이터베이스에서 정한 무결성 제약 조건을 항상 만족해야 한다.격리성(Isolation)동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리한다. 예를 들어 동시에 같은 데이터를 수정하지 못하도록 해야 한다. → 격리성은 동시성과 관련된 성능 이슈로 인해, 트랜잭션 격리 수..