재미있게 이해하고 생각해보자!! 마인드를 가지는 개발자 남기호입니다!!
오늘은 갑자기 블로그를 쓰고 싶어서 트랜잭션 격리 4가지를 이야기를 해볼까 합니다.
물론 재미있게 이야기하는거 히히!
트랜잭션에서는 4가지에 트랜젝션 격리가 있어요
첫번째 부터 이야기를 해볼까 합니다!
트렌젝션에서
데이터베이스에서 트랜잭션 격리 수준은 여러분이 데이터를 다루는 방식을 어떻게 설정할지 결정하는 중요한 설정입니다. 마치 여러분이 카페에서 커피를 마시면서 노트북으로 작업을 하는데, 옆 테이블에서 무슨 일이 벌어지고 있는지 얼마나 신경 쓸 것인가를 결정하는 것과 비슷해요. 그럼, 재미있고 편하게 각 격리 수준에 대해 이야기해 볼까요?
마치 커피숍에서 옆 테이블 사람이 주문한 아직 나오지 않은 음료를 맛보는 것과같다고 볼수있지요. 데이터베이스에서는 이 수준이 가장 낮은 격리 수준이며, 다른 트랜잭션이 아직 끝나지 않은텍스트 변경사항까지 볼 수 있어요. 이로 인해 더티 리드가 발생할 수 있는데, 마치 아직 준비되지 않은 음료를 마시는 것처럼 예상치 못한 결과를 얻을 수 있습니다. 그러나 이것은 로깅이나 모니터링처럼 데이터의 최신성이 중요하고 정확성이 그다지 중요하지 않은 경우 유용할 수 있어요.
더티 리드(Dirty Read) 란 이게 뭐고??
는 한 트랜잭션이 아직 완료되지 않아 최종적으로 커밋되지 않은 데이터를 다른 트랜잭션이 읽는 현상을 말합니다. 쉽게 말해, 한 프로세스가 처리 중인, 아직 확정되지 않은 데이터를 다른 프로세스가 미리 읽어버리는 것이죠
역시 저또한 완벽하게 이해가 안되서 일상 생활을 잘 비유하는데 예를 들어, 한 사용자가 은행 계좌에서 돈을 인출하는 트랜잭션이 있습니다. 이 트랜잭션이 아직 완전히 마무리되지 않았는데, 다른 사용자가 동일한 계좌의 잔액을 조회한다고 가정해 보겠습니다. 만약 두 번째 사용자의 트랜잭션이 더티 리드를 하게 되면, 아직 완료되지 않은 인출 작업의 중간 상태를 볼 수 있게 됩니다. 이 경우, 두 번째 사용자는 잘못된 잔액 정보를 받게 되고, 이는 데이터 무결성 문제로 이어질 수 있습니다! 그럼 데이터 무결성을 무조건 유지할려면 사용하면 안되겠지요????
이제 커피숍에서 옆 사람의 음료가 서빙되기를 기다렸다가 마시는 것으로 생각해 보세요. 즉, 다른 사람의 주문이 완전히 처리되고 나서야 그 결과를 볼 수 있어요. 이는 더티 리드를 방지하지만, 한 트랜잭션 내에서 같은 데이터를 두 번 읽을 때 다른 결과를 볼 수 있는 논리피티 리드는 여전히 가능합니다. 대부분의 웹 애플리케이션에서 이 격리 수준이 기본으로 사용되며, 꽤 균형 잡힌 선택지입니다.
논리피티 리드(Non-repeatable Read)는 뭐고??
한 트랜잭션 내에서 같은 쿼리를 두 번 실행했을 때 다른 결과를 받는 현상을 말합니다. 이는 한 트랜잭션이 진행 중일 때 다른 트랜잭션이 데이터를 수정하거나 업데이트함으로써 발생합니다.
예를 들어 볼게요 . 한 사용자가 은행의 데이터베이스에서 자신의 계좌 잔액을 조회하는 트랜잭션을 실행한다고 가정했을때 사용자는 처음에 잔액을 조회하고 어떤 작업을 수행한 뒤에 다시 잔액을 조회합니다. 만약 이 사용자의 두 번째 조회 사이에 다른 사용자가 같은 계좌에 대해 입금 트랜잭션을 실행하고 커밋한다면, 첫 번째와 두 번째 조회 결과가 달라지겠지요. 이러한 현상이 바로 논리피티 리드입니다.
커피숍에 앉아서 여러분이 주문한 동일한 커피를 여러 번 주문할 때마다 정확히 같은 맛과 품질을 기대하는 것과 비슷해요. 트랜잭션 동안 조회한 데이터는 변경되지 않으며 일관성이 유지됩니다. 하지만 새로운 데이터(새로운 주문)가 생겨 그것이 조회 결과에 반영될 수 있습니다, 팬텀 리드가 발생할 수 있습니다. 은행 거래와 같이 일관성이 매우 중요한 경우에 적합한 수준이죠.
팬텀 리드(Phantom Read)는 뭐고 ??
한 트랜잭션 내에서 일관된 쿼리 결과를 얻지 못하는 현상을 말합니다. 구체적으로 말하자면, 한 트랜잭션이 동일한 쿼리를 두 번 실행할 때, 첫 번째 쿼리 실행과 두 번째 쿼리 실행 사이에 다른 트랜잭션이 데이터를 삽입하거나 삭제함으로써 첫 번째와 두 번째 쿼리의 결과가 달라지는 것을 말합니다.
팬텀 리드의 가장 큰 문제는 한 트랜잭션 내에서 데이터의 일관성이 보장되지 않는다는 것입니다. 예를 들어, 한 트랜잭션에서 특정 조건에 맞는 데이터의 수를 두 번 세어야 한다고 가정해 봅시다. 첫 번째 쿼리를 실행한 후, 그리고 두 번째 쿼리를 실행하기 전에 다른 트랜잭션이 해당 조건에 맞는 새로운 데이터를 삽입한다면, 두 번째 쿼리의 결과는 첫 번째 결과와 다를 것입니다. 이처럼 두 번의 쿼리 사이에 데이터베이스의 상태가 변경되어 발생하는 불일치를 팬텀 리드라고 합니다.
팬텀 리드를 방지하기 위해서는 격리 수준을 REPEATABLE READ 이상으로 설정해야 합니다. 특히, 가장 높은 격리 수준인 SERIALIZABLE에서는 트랜잭션들이 마치 순차적으로 실행되는 것처럼 격리되어 팬텀 리드를 포함한 모든 읽기 이상 현상을 방지할 수 있습니다.
말한것처럼 이제 진짜 마지막 하이레벨~~ 두구두구두두구.... 그냥 최고에 리드란 리드를 다 잡을수 있는 SERIALIZABLE !!
가장 엄격한 격리 수준으로, 마치 커피숍에서 여러분 혼자만이 주문을 할 수 있고, 다른 모든 사람은 여러분이 주문을 완료할 때까지 기다려야 하는 상황과 같아요. 이 격리 수준에서는 트랜잭션이 서로 영향을 주지 않아 완벽한 데이터 일관성을 보장하지만, 동시에 여러 트랜잭션을 처리하는 능력이 크게 떨어질 수 있습니다. 따라서 이 격리 수준은 주식 거래나 금융 이체와 같이 데이터의 정확성이 매우 중요한 작업에 적합합니다.
각 격리 수준을 선택할 때는 데이터의 정확성과 처리 성능 사이에서 어떤 것을 더 중요시할지 결정해야 합니다. 당신의 애플리케이션이 무엇을 필요로 하는지 이해하고, 그에 맞는 격리 수준을 선택하세요. 이렇게 각 상황에 맞는 격리 수준을 적절히 선택하는 것이 데이터 일관성과 시스템 성능을 최적화하는 열쇠입니다!
해당되는거는 단점이 있어요 일관성은 진짜 좋은데 여러 트랜잭션을 처리 할때는 엄청 느려요 순차적으로 전부 commit 을 하면 그다음에 다른 트랜젝션을 처리하니까요 혹시 물어볼수도있어요 그냥 전부다 SERIALIZABLE 트랜잭션 격리를 사용하면 되잖아요!! 아니죠 그러면 다 느려요 전부다 API 나 데이터베이스가 처리하는데 Select는 빨라야되는데 그것도 느리면 그 서비스 누가 쓰겠어요!! 어려울거없어요 더 디테일한거는 위키에서 보면 되지만 여기서 요점 트랜잭션을 사용을 할때 내가 지금 어떤 트랜젝션을 사용하고 어떤 상황일때 써야하는지 사용하자!! 이렇게 되면 아 알아야 사용하는구나 라고 생각 했으면 좋겠어요 공부라고 생각하지마세요 재미있게 느낌있게 ~~~
재미있었길 바랄게요 히히!!