제 경험이 조금씩 첨가된 주관적인 답변이므로 참고만 하세요! 답이 아닙니다! 여러분의 의견을 존중합니다!

멀티스레드 환경에서 안전한 코드를 작성하기 위한 방법 중 어떤 동기화 기법이 있을까요?

현업에서 데이터 정합성을 위해 알바를 고용해 데이터를 정합성을 맞출일이 있었고 이때 하루에 50명이 사용할 단기성 애플리케이션을 만드는 프로젝트가 있었습니다. 프로젝트를 진행하다 우연히 여럿이서 동시에 따닥하고 눌렀고 여러개의 데이터가 동시에 들어와버렸습니다.

이게 여러번 있었고 동시성에 대해서 고민했었습니다. 너무 짧은 기간에 완성해야하는 프로젝트라 코드에 손을 대지 못하고 나중에서야 데이터 정합성을 재검사 하면서 스크립트로 이중 데이터를 삭제했습니다. 그러고 나중에 동기화에 대해서 더 공부하면서 여러가지 방법이 있다는 것을 알게 됐습니다.

멀티스레드 환경에서 동시에 두번 요청이 되어 DB에 동시에 접근하는 것을 막기위한 방법으로 첫번째, queue에 담았다가 하나씩 꺼내어 처리하는 방법 두번째, upsert 쿼리를 이용하는 방법 세번째, db의 unique 무결성을 이용하는 방법을 공부했습니다.

애초에 요청이 두개 들어왔을때 문제가 스프링에 있다고 생각했고 스프링에서 코드로 해결하려고 했습니다. 스프링은 각 요청마다 스레드를 다르게 생성하고 , 각 스레드는 스택을 다 따로 쓰기 때문에 여러 스레드가 하나의 인스턴스를 참조합니다. 이는 동시성 문제를 가질 수 있는 상황을 만들 수 있습니다.

싱글톤 패턴으로 만들어진 서비스의 메소드를 여러개의 스레드가 참조합니다. 그렇기 때문에 처음엔 서비스의 메소드에 동기화 로직을 만들 생각이었습니다. 여러 스레드가 하나의 인스턴스를 참조하는 문제를 해결하기 위해 @Synchronized나 synchronized 블록을 사용하여 메소드 영역을 동기화하려고 했습니다.

이 경험을 통해 어떤 동시성 문제가 발생할 수 있는지 사전에 파악하는 것도 중요하다는 것을 느꼈습니다.


참고한 내용

댓글남기기