도라지보다더덕
280
2021-07-26 11:18:45
4
191

DB에 업데이트 쿼리가 많이 생성될 때


안녕하세요.


현재 백엔드 공부중인 학생입니다!


공부 중에 궁금한 점이 생겨서 질문드립니다


만약 디비에 저장된 수치에 +1을 한다고 했을 때 이 쿼리가 동시에 많이 나간다면 어떻게 대처를 해야할까요?


디비 고립레벨를 repeatable read로 하고 동시에 쏜다면 정상적으로 동작하지 않을거라고 생각되는데

(ex, 디비 저장값: 10, 두개의 쿼리가 나간다면 둘다 10을 가져오고 +1 씩 되므로 12가 아닌 11이 된다)


그렇다고 고립 레벨을 serializable로 하거나 비관적 락을 사용하거나 한다면 수많은 쿼리가 생성될 때 병목현상이 일어난다고 생각되서요


혹시 이럴 경우는 어떻게 대처하시나요? 궁금합니다!

0
  • 답변 4

  • ghkdwls30
    2k
    2021-07-26 11:28:41 작성 2021-07-26 11:29:20 수정됨

    자 보통 개발자들은

    SELECT 컬럼 + 1 하여 넣기도합니다만 말씀하신데로 repeatable read ( 마이에스큐엘 디폴트) 상태든 commit read ( 오라클 디폴트)  이든 

    동시성에서 문제가 발생합니다.

    두 트랜젝션 T1, T2에서 동시에 같은 데이터를 가져왔을 경우 같은 번호를 리턴하겠지요 


    그래서 락(컬럼락 혹은 로우락)을 거는 수밖에없습니다. 

    동시성을 제처두고서라도 데이터의 일관성이 중요하니까요


    보통 웹어플리케이션에서는 동시성제어를 위해서 DB락이 아닌 소스레벨에서의 락을 사용하기도합니다.


    그래서 해당 작업이 동시성이 더 중요한가? 일관성이 더 중요한가에 따라 좀 달라집니다.





  • 쿠잉
    4k
    2021-07-26 11:33:28

    단순히 유니크한 증가값을 원하면 auto incremental 을 쓰거나 timestamp를 쓰는것도 방법이고요

    꼭 특정 숫자를 를 가지고  +1하겠다 라면 select for update 등으로 트랜잭션 고립화를 높일수있겠고요

    근데 보통의 경우 auto increment로 될것 같네요

    그리고 isolation의 경우 read-commit 도 많이 쓰는 추세입니다

  • 도라지보다더덕
    280
    2021-07-26 11:53:10

    어쩔 수 없이 실시간을 포기해야하는군요 ㅠㅠ


    두분 다 감사합니다!

  • 안전라이딩
    1k
    2021-07-26 14:13:47 작성 2021-07-26 14:16:01 수정됨

    테이블의 컬럼은 일정 단위 (100 , 1000, 1000 ?) 로 증가 시키고 단위 내에서는 코드 레벨에서 automic 연산 시키기도 합니다. 예외가 나거나 문제가 발생하면 해당 구간은 버리고 다시 시작하거나 다음 구간으로 점프하거나 합니다. 게임서버에서 아이템 아이디 발급을 이런식으로 처리했었습니다.

  • 로그인을 하시면 답변을 등록할 수 있습니다.