평소와 똑같이 회사에서 업무를 보는데 한가지 문제를 만나게 되었다. 그것은 아래 그림과 같이 view에서 전달된 파라미터를 통해 관계가 있는 두 테이블에 동시 insert 하는 방법이였다.
사실 해당 요청을 처리하는 하나의 컨트롤러에서 2개의 mapper를 사용하면 고민 없이 처리할 수 있었지만 그러고 싶은 생각은 없었다. 해당 문제를 해결하면서 성장하고 싶은 생각도 있었고, 코드를 좀 더 깔끔하게 만들고 싶었다.
그러나 1시간...2시간...시간은 점점 흘러갔고, 해당 기능을 구현하는데 써야하는 시간이 다가올수록 초조해졌다. 그래서 같은 회사 개발자들에게 평소에 이러한 기능을 구현할 때 어떤식으로 진행하시는지 물어보거나 위코드 단톡방에 헬프콜을 보냈는데 같이 문제 해결해주시는 모습에 감동을 먹었다😭
위처럼 정말 많은 분들이 도와주신 덕분에 문제를 해결할 수 있었고, 내가 이 문제를 해결하기 위해 알아낸 여러가지 방법은 다음과 같다.
- 내가 아까 위에서 말했던 mapper를 두 개 만들어서 한번에 insert한다.
- 예전 내 블로그 포스팅을 보면 mybatis에서 제공하는 selectKey 를 통해 하나의 mapper로 처리한다.
- spring에서 제공하는 transaction 어노테이션을 활용한다.
- 쿼리를 짤 때 transaction을 통해 두 개의 insert문을 한번에 처리한다.
일단 회사 업무를 처리할 때 선택한 방법은 4번이였다. 그러나 트랜젝션에 대한 개념 또한 없었고, 이번 기능구현을 통해 처음 알게 되었는데 좋은 공부가 되었다. 일단 위에서 말한 문제를 해결한 쿼리를 공개하면서 트랜젝션을 간략하게 설명해보려고 한다.
트랜잭션
이란 거래
라는 뜻으로 데이터베이스 내에서 하나의 그룹으로 처리되어야 하는 명령문들을 모아 놓은 논리적인 작업 단위를 의미한다. 트랜젝션을 사용할 때 다음과 같은 특징을 가지며 이를, ACID
라고도 부르니 알아두면 좋을 거 같다.
원자성은 트랜잭션이 DB에 모두 반영되거나, 전혀 반영되지 않거나를 뜻한다.
All or Nothing을 생각하면 된다.
일관성은 트랜잭션 작업 처리의 결과가 항상 일관되어야 한다를 뜻한다.
즉, 데이터 타입이 반환 후와 전이 항상 동일해야 한다.
독립성은 하나의 트랜잭션은 다른 트랜잭션에 끼어들 수 없고 마찬가지로 독립적임을 의미한다.
즉, 각각의 트랜잭션은 독립적이라 서로 간섭이 불가능하다.
지속성은 트랜잭션이 성공적으로 완료되면 영구적으로 결과에 반영되어야 함을 뜻한다.
보통 commit 이 된다면 지속성은 만족할 수 있다.
트랜젝션을 사용함에 앞서 3가지 중요 요소가 있는데 다음과 같다.
BEGIN select ~~~ insert info ~~~ update ~~ COMMIT
COMMIT
ROLLBACK
연산을 만나기 전까지 말이다. COMMIT
한 곳까지만 복구한다.위는 내가 문제를 해결한 쿼리를 공개한다. 사진을 찍는 과정에서 맨 밑에 COMMIT이 빠지긴 했지만...넘어가자...🙄 일단 간략한 설명을 하자면
inserted
라는 임시테이블을 생성 후 첫번째 insert문을 실행한다.insert_detail
의 임시 테이블에서 두번째 insert문을 실행한다.사실 좀 더 글을 이쁘게 쓰고 싶었는데 내 글쓰기 능력이 여기까지라 너무 난잡해 보이기도 한다. 하지만 위의 문제를 해결함과 동시에 시간이 지나면서 내 글쓰기 능력도 어떻게든 해결이 될거라 생각한다(?)
암튼 많은 도움을 주신 위코드 동기분들, 지인분들에게 너무 감사하고 추후 시간이 된다면 위에서 설명 못한 나머지 3가지 방법도 정리해서 올릴 생각이다. 끝!