모범 사례: 경합 조건 피하기 🚘💥🚗😰

3880 단어 rubydatabasesecurity
다음은 경합 상황에 대처하기 위한 몇 가지 시나리오와 팁입니다.

경쟁 조건 이해



A computer program is like a horse race. The computer program does several things at the same time, similarly to how several horses run at the same time in a horse race. Each horse represents what is usually called a thread of execution. That way, one such thread may handle network communication, another one may be responsible for redrawing the user interface. In the case of a race condition, the application works properly if a given horse wins the race. For example, the application may work if horse number five wins, but it will crash if any other horse wins the race. Source https://simple.wikipedia.org/wiki/Race_condition.



실제 사례: 많은 사용자가 동시에 같은 방을 예약합니다.



예약 앱이 있다고 가정하고 Room 모델이 있다고 가정해 보겠습니다. rooms 테이블은 user_id 를 저장합니다.

class Room
  def assign_to_user!(user_id)
    self.user_id = user_id
    self.save!
  end
end


괜찮아 보이죠? 아니요, 두 명의 사용자가 동시에 동일한 예약을 하면 심각한 문제가 발생할 수 있습니다. 여기 이유가..

양식을 제출한 첫 번째 사용자는 데이터베이스 트랜잭션을 열고 다른 데이터베이스 트랜잭션을 연 후 밀리초를 제출한 두 번째 사용자를 엽니다. 이제 두 개의 데이터베이스 트랜잭션이 열려 있고 두 번째 트랜잭션이 첫 번째 트랜잭션을 재정의했습니다. 즉, 첫 번째 사용자는 방값을 지불했지만 두 번째 사용자는 방을 얻었습니다, LOL. 두 호스트가 로비에서 토론하는 것을 상상해 보십시오. "아니요, 방을 예약했습니다!"라는 말을 듣게 될 것입니다.



이를 방지하기 위해 룸 테이블을 잠글 수 있습니다.

class Room
  def assign_to_user!(user_id)
    # This block is called within a transaction,
    # room is already locked.
    with_lock do
      self.user_id = user_id
      self.save!
    end
  end
end



테이블을 잠그면 두 개의 요청이 동시에 발생하더라도 DB 잠금이 해제될 때까지 레코드를 업데이트할 수 없습니다. 이를 "비관적 잠금"이라고 합니다.

앱에서 이런 종류의 일이 발생할 가능성이 높다는 것을 알 때마다 비관적 잠금을 사용하세요. 여기에서 전체 문서 및 예를 참조하십시오. https://api.rubyonrails.org/classes/ActiveRecord/Locking/Pessimistic.html



기타 시나리오



다음은 원하지 않는 경합 상태를 피하기 위해 데이터베이스 잠금을 구현해야 하는 경우의 작은 목록입니다.
  • 금전거래
  • 항공편 예약
  • 예약하기
  • 암호화폐 거래
  • 도박

  • 결론 및 다음 단계



    응용 프로그램의 어떤 부분에 데이터베이스 잠금이 필요한지 생각하고 모든 사용자가 훌륭한 경험을 할 수 있도록 해당 영역을 패치할 수 있기를 바랍니다.

    질문이 있거나 Optimistic Locking과 같은 다른 종류의 데이터베이스 잠금 메커니즘에 대해 대화하고 싶은 경우 알려주십시오.

    좋은 웹페이지 즐겨찾기