완전히 성공하거나 실패해야 하는 트랙잭션의 원자성 개념은 알겠지만, 좀만 더 생각해보면

세션이 트랜잭션을 시작하고 데이터를 수정하는 동안에는 커밋이나 롤백 전까지 다른 세션에 서 해당 데이터를 수정할 수 없게 막아야 한다.

아래 그림처럼 세션1도 접근하고 싶고 세션 2도 접근하고 싶은 상황에서 문제가 발생할 것이다! 여기서 DB는 락 이라는 개념을 제공한다!

image.png

세션이 변경을 시도할 때 락을 먼저 획득해야 변경을 할 수 있다! 그러므로 락이 있는지 먼저 확인한다!

image.png

락이 남아 있으므로 세션1은 락을 획득한다. (세션1이 세션2보다 아주 조금 더 빨리 요청했다.)

image.png

세션2도 변경을 시도하려면 해당 로우의 락을 실행해야 하는데 락이 없으므로 돌아올 때까지 대기한다! 이런 방식으로 트랜잭션의 원자성을 보존하는 것이다!

commit을 실시해서 트랜잭션을 종료시킨다면, 세션1은 락을 반납할 것이다. 그러고 나면 세션2가 락을 획득하고 변경을 시도할 것이다!

참고로 세션2가 락을 무한정 대기하는 것은 아니다. 락 대기 시간을 넘어가면 락 타임아웃 오류가 발생한다. 락 대 기 시간은 설정할 수 있다.

아래 쿼리문처럼 lock의 타임아웃을 정해놓을 수 있고, autocommit mode가 off 되어 있어야 바로 commit하지 않으므로 락을 갖고있음을 확인할 수 있을 것이다! 실제로 다른 DBA에서 해당 테이블에 변경을 시도하면 기다리게 된다!!

SET LOCK_TIMEOUT 60000;
set autocommit false;
update member set money=1000 where member_id = 'memberA';