더북(TheBook)

그래서 게임 서버를 만들다 보면 데이터베이스 트랜잭션이 그렇게까지 필요하지는 않습니다. 게임 서버가 데이터베이스에 있는 레코드 2개 이상에 플레이어 데이터를 저장하다 어떤 오류가 발생해서 둘 중 하나를 저장하지 못했다면 일관성이 깨질 것입니다. 그러나 이러한 일은 자주 발생하지 않습니다. 데이터베이스의 트랜잭션 기능은 주로 논리적 실패(Money가 음수가 된 경우 등) 때문에 롤백할 때 사용하는 것이 대부분입니다. 즉, 게임 서버 메모리에서 사전 검증을 다 해 버리는 특성 덕분에 트랜잭션이 꼭 필요한 상황은 적다고 보면 됩니다.

게임 서버에서 사전 검증을 마쳤다고 하더라도 중간에 크래시가 나는 위험성 등을 고려하지 않을 수 없습니다. 예를 들어 앞의 예시 코드 아래쪽에 있는 질의 구문을 실행하던 중 두 번째 것을 하기 직전에 게임 서버에서 크래시가 나면 어떻게 될까요? 데이터베이스에는 두 플레이어의 아이템 교환 결과가 잘못 저장되고 말 것입니다. 이러한 경우라면 트랜잭션이 필요해 보입니다.

그러나 트랜잭션으로 발생하는 성능 저하와 데드락 가능성을 완전히 없애고 싶을 수도 있습니다. 이렇게 레코드를 2개 이상 기록하되 전부 아니면 전무하게 기록하는 동시에 트랜잭션을 사용하기 어려운 상황이라면 어떻게 해야 할까요?

여러 가지 방법이 있습니다만, 일단 어딘가에 로그를 남겨 놓고 두 플레이어의 레코드를 업데이트하는 것입니다. 그리고 두 레코드의 업데이트가 완료되면 해당 로그를 지워 버리는 것이죠. 또 다른 방법으로는 트랜잭션에서 발생하는 잠금 수준을 완화하는 것입니다. 완벽하지는 않지만 쉬운 다른 방법은 트랜잭션의 잠금 수준을 “다른 곳에서도 읽기 하는 것을 허락한다.”라고 변경하는 것입니다.

그러나 이렇게 하면 데이터베이스의 ACID 특징을 다소 위반하게 됩니다. 물론 그 대신 우리는 데드락이 매우 적거나 없어지는 효과를 볼 수 있으니 일장일단의 선택인 셈입니다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.