주요글: 도커 시작하기
반응형
자바캔에 Hibernate에 대한 글을 올리면서 동시에 지금 다니고 있는 회사의 서비스 사이트인 www.uasis.com을 Hibernate를 기반으로 구축하고 있었습니다. 사용하는 DBMS는 오라클인데, 기존 테이블 중에는 시퀀스를 사용해서 PK를 생성하는 것도 있었고, 또는 그냥 최대값에서 1을 더한 값을 PK로 사용하는 경우도 있었습니다.

마침 Hibernate는 이 두가지 모두를 지원했고, 최대값에 1씩 증가한 값을 PK로 사용하는 테이블의 경우 Hibernate의 PK generator로 increment를 선택하였습니다. increment generator는 최대값에 1을 더한 값을 자동으로 PK 값으로 생성해주는 기능을 제공하는 것이었기에 딱 맞았다고 생각했습니다.

그런데, 운영을 하다보니 이상한 현상이 발생했습니다. 예를 들어, 테이블에 저장된 PK의 최대값은 100인데, Hibernate는 자꾸 97이라는 숫자를 PK로 생성하려드는 것이었습니다. 서버를 내렸다 올리면 다시 101부터 올바르게 생성하구요,,,

뭐가 이상할까 고민하다가 서버가 두대인 점이 떠올랐습니다. (저희 회사는 WWW를 제공하는 서버가 두대이며, L4를 사용해서 적당히 요청을 분산하고 있습니다.) 그래서 몇가지 테스트를 해 봤더니,, 이게 왠걸.. increment는 분산환경에서는 올바르게 동작하지 않는 것이었습니다. Hibernate API 문서에도 나와 있더군요. (분산환경에서 보장할 수 없다라구요..)

그래서 결국 increment generator의 소스 코드까지 보게 됐는데, 동작 방식이 초기에 한번만 최대값을 구하고 이후부터는 최초에 구한값에서 계속 1씩 증가하는 방식이었습니다. 그래서 A 서버에서 구한 최대값이 100이고, (A와는 다른 시점에 최대값을 구한) B 서버에서 구한 최대값이 105가 되는 엉뚱한 사태가 발생하고 만거죠.

그래서 결국 분산환경에서도 올바르게 동작하는 increment와 비슷한 PK generator를 만들어서 이 문제를 해결했습니다.

만약, 처음에 generator 를 사용할 때 API 문서의 '분산환경에서는 보장할 수 없다'라는 그 한줄만 읽어봤더라도 버그 때문에 불필요한 시간을 허비하진 않았을텐데 말이죠.

뭔가 남이 만든 기능을 사용한다면, 무턱대고 사용하기 보다는 먼저 문서를 자세히 한번 읽어본 뒤에 작업해야 한다는 것을 또 다시 느끼고 말았습니다. 여러분은 저처럼 뻘짓 디버깅을 하지 마세요.

+ Recent posts