갑자기 궁금한 게 생겼다...
비동기로 로직을 태우면 트랜잭션 관리를 어떻게 하지?
서론은 뭔가 원리부터 해야할 것 같아서, 시리즈의 처음엔 원리에 대해 기록해두려 한다.
바로 동기와 비동기 그리고 비슷한 개념인 블로킹과 논블로킹이다.
(얼른하고 실습으로..)
이 주제로 이미지를 찾다보면 대학교때 봤던 이미지가 항상 따라온다.
첫번째로는 이런 이미지가 있고
두번째로는 이런 이미지가 대표적이다.
두개 다 내용을 이해하는데 도움이 되지만, 나는 아래의 사진을 선호한다.
단순히 동기는 이렇고 비동기는 저렇다.
말하기 전에, 운영체제 동작 방식중의 하나를 알고 있으면 좋을 것 같다.
위키백과에서는 System call 을 아래와 같이 정의하고 있다.
간단히 syscall 은 운영 체제의 커널이 제공하는 서비스에 대해, 응용 프로그램의 요청에 따라 커널에 접근하기 위한 인터페이스이다.
운영체제에 대한 자세한 얘기는 각설하고, 예를 들면 CPU와 같은 실제 하드웨어 장치를 얻기(입출력) 위한 권한은 운영체제가 쥐고 있다.
그래서 Applications 레이어, 즉 C언어 등으로 만들어진 프로그램이 직접 system call을 할 수는 없으므로 API를 만들어둔 것이라고 보면 된다.
그리고 실제 우리가 프로그래밍을 하면 커널에 I/O 모델이 움직인다.
이제 SysCall 을 알았으니, 비동기도 알 수 있을 것 같다. 원리는 되게 쉽다.
일반적으로 뭔가 호출을 했으면 그 결과를 기다려야한다.
즉, 어플리케이션 계층에서 커널에 시스템 호출을 하면, 그 결과를 어플리케이션 계층에서 기다린다.
그런데 이 때, 기다리면서 딴짓을 할지 or 얌전히 기다릴지를 선택할 수 있는 것이다.
이렇게 볼 수 있다.
중요한 것은 리턴 값이다.
결과를 받아야 해서 (동기) 기다리고 있던건데, 비동기로 처리한다면 결과를 어떻게 하지?
하는 의문이 들 수 있다.
비동기는 콜백함수를 포함해서 던져준다.
예를 들면 SysCall을 하면서 "너 작업 끝나면 알아서 이쪽으로 콜해~" 라고 알려준 것이다.
그러므로 커널은 본인의 작업이 끝나면 콜백함수를 타고 넘어가면서 어플리케이션 계층에서는 굳이 그 작업이 끝났는지 어쨌는지 기다릴 필요 없이 자기가 할 것(다른 코드)을 실행하면 되는 것이다.
그럼 여기서 블로킹과 논블로킹의 개념이 파생되어 나온다.
이것도 원리는 사실 어렵지 않다.
동기는 넘겨준 작업이 끝날때까지 아무것도 하지 못한 채로 기다려야 하는 것이고.
비동기는 작업을 독립적으로 맡기고 나는 다른 걸 실행하는 것이다.
그런데 사실, 자신의 코드를 계속해서 실행하려면 논블로킹 상태여야 한다.
다시 말해, 비동기는 다른 작업을 실행할 수 있는 환경이 세팅된 것 일 뿐, 만약 비동기-블로킹 조합이라면 어차피 기다려야 된다.
이 말이 아이러니하게 느껴지는 것처럼 실제로 이런 조합은 별로 없다.
아무튼 블로킹 쪽을 정의하면
일종의 권한 문제라고 비유할 수 있겠다.
비동기로 환경을 갖춰놔도 블로킹으로 권한이 없으면 실행불가X
동기로 기다려야 되는 환경인데 논블로킹으로 권한이 있으면 실행가능O
그래서 최종적으로 4가지의 경우가 나온다.
그럼 이제 위의 각각의 경우를 하나하나 요약해서 설명할 수 있다.
동기-블로킹 : 환경도 기다려야되는 환경이고, 실제 권한도 없으므로 커널에 요청시에 커널이 작업을 끝내고, 끝났다고 전달해줄때까지 가만히 기다려야한다.
동기-논블로킹 : 기다려야되는 환경인데, 내 코드를 계속 실행할 권한은 있어서 커널에 요청해두고 내 코드를 계속 실행한다. 다만, 기다려야된다는 건, 결과를 알아야한다는 것이므로 내 코드를 실행하는 동안 "커널아 작업 끝났니?" 이걸 계속 물어보면서 끝난걸 확인한다.
비동기-블로킹 : 어플리케이션에서 하던거 계속 해도 되는 환경이다. 때문에 커널 호출할때 콜백함수를 포함한다. 근데 블로킹이라서 내 코드를 진행할 권한이 없기 때문에 콜백을 던져두고도 기다릴 수 밖에 없다.
비동기-논블로킹 : 아마 결국 이 걸 쓸 것이다.
콜백함수를 던져서 알아서 하라고 하고 내 코드를 계속 실행할 수 있는 환경(비동기)을 갖추고, 실제 그럴 수 있는 권한(논블로킹)까지 있어서 계속 내 코드를 실행하면 된다.
이렇게 원리를 설명하고 나면 의아해지는 게 있다.
서론에 말한 것 처럼, 비동기는 트랜잭션 관리를 어떻게 하는가
다 이걸 파악하기 위한 빌드업이었다..
이제 전반적인 내용을 이해했으니, 비동기 프로그래밍을 실습해 나가면서 최종적으로 트랜잭션 관리까지 알아보도록 하자!
물론 이건 코드로!