H2 DB이용해서 Lock 이해해보기

Yellta·약 17시간 전
0

study

목록 보기
11/11

계좌이체 예시를 통해서 Lock을 알아보자

Transaction이 시작되면 사용자는 데이터에 쓰기, 읽기를 수행할 수 없다.
락이 걸려있기 때문에

계좌이체를 수행한다고 가정하자

  1. data1사용자는 계좌이체를 위해서 Lock을 획득한다. 즉 데이터를 사용하고 있다는 뜻이다. data1사용자는 돈을 인출할 예정이다. - data1이 lock을 가짐
  2. data2사용자는 data1사용자에게 어플을 통해 계좌 이체를 수행하려고 한다. 하지만 data1이 사용중이기 때문에 대기한다.(Lock획득 대기)
  3. data1사용자가 정상적으로 돈을 인출했다.(Lock반환)
  4. data2사용자는 Lock을 얻고 data1에게 돈을 보낸다.

만약에 2번의 상황에서 Lock없다면?
그리고 2번의 상황에서 에러가 발생해 rollback을 수행했다면??

data1사용자는 계좌는 2000원을 인출하려고 한 상태이다. 근데 그 과정에서 에러가 발생했다.
data2 사용자는 에러가 발생하기 직전에 data1에게 계좌이체를 수행했다. 그때 계좌는 2000원이 빠진 8000원이었다. 거기에 10000원의 돈을 송금했다. (data1: 18000원, data2: 10000->0원)
하지만 data1의 사용자는 에러가 발생한 상태로 db를 원래 금액인 10000원으로 되돌렸다.
최종 결과는 data1 : 10000원 data2:0원
즉 돈을 순식간에 잃어버렸다.

대충 lock이 뭔지 알게되었으니 h2 DB로 함께 확인해보자!

H2 DB로 실습해보기

Autocommit을 false로 두고 위의 명령어를 실행하자
참고로 Commit 명령어를 치지 않으면 계속 데이터를 점유하고 있는 상태가 된다.

두 번째 세션에서 해당 명령어를 작성해보자 사진을 보면 update구문은 수행되지 않았다.
lock이 걸려있기 때문이다. 트랜잭션의 락 대기 시간을 10초로 제한해두었다.

10초가 지난후의 모습이다.
10초가 지나도 Lock을 획득하지 못해서 에러가 발생하게 된다. 즉 commit을 수행하지 못한 것이다.

이제 첫 번째 세션에서 commit을 하고 결과를 확인해보자

첫 번째 세션에서 수행한 update구문이 잘 수행되었다. 하지만 두 번째 세션에서 수행한 40000원으로 update하는 로직은 수행되지 않았따.

그렇다면 두 번째 세션에서 40000원으로 update하려면 어떻게 해야할까?

바로 두 번째 세션이 기다리고 있는 lock타임이 끝나기전에 첫 번째 세션에서 commit 즉 transaction을 완료하면 된다.

첫 번째 세션에서 commit을 수행하기 전

첫번째 세션에서 commit을 수행하니까 바로 두 번째 세션에서 update가 수행되었다!

REVIEW

트랜잭션의 개념만 알고 있었는데 DB로 실행해보니까 좀 더 감이 잘 잡히는 느낌이다. ㅎㅎ


참고

김영한 선생님의 스프링 입문 강의를 보고 작성했습니다 ㅎㅎㅎ

profile
Yellta가 BE개발해요! 왜왜왜왜왜왜왜왜왜왜왜왜왜왜왜왜왜왜왜 가 제일 중요하죠

0개의 댓글