2011-06-11 1 views
1

사용자 프로필이 표시 될 때마다 사용자 테이블의 정수 카운터를 업데이트합니다.rails 3 & activerecord : 카운터 필드를 업데이트하기 위해 특별한주의가 필요한 잠금 조치가 필요합니까?

나는 높은 동시성 상황에 대해 생각하기 시작했다. 그리고 많은 사람들이 동시에 사용자 프로필 페이지를 쳤다면 어떻게 될지 궁금해했다. 레일스/액티브 레코드가 나를 위해 레코드 잠금 및 세마포어를 마법처럼 처리합니까?

또는 내 업데이트 메소드를 동시에 호출 할 때 내 앱이 업데이트 이벤트 누락을 피하기 위해 명시 적으로 어떤 메커니즘을 호출해야합니까?

def profile_was_hit 
    self.update_attributes :hitcounter => self.hitcount + 1 
end 

그리고 그 라인을 따라 , 내가 Users.increment_counter 같은 것을 사용해야 할 때 (: 방문 횟수 카운터, self.id) 대신?

답변

4

기본 구성에서 단일 Rails 인스턴스는 한 번에 하나의 요청 만 처리하므로 응용 프로그램 계층의 동시성 문제에 대해 걱정할 필요가 없습니다.

응용 프로그램의 인스턴스가 여러 개 실행중인 경우 (아마도/할 것입니다.) 모든 응용 프로그램 인스턴스가 서로 이야기하지 않고 데이터베이스에 요청을 보냅니다. 따라서 은 데이터베이스 계층에서 처리됩니다. MySQL, PostgreSQL 등은 모두 write시에 행을 잠글 것이다.

이 상황을 처리하는 방법은 응용 프로그램이 값을 읽고, 값을 증가시키고, 쓰기 때문에 성능에 이상적이지 않습니다. 읽기와 쓰기 사이의 지연으로 인해 값을 놓칠 수 있습니다. 증분 책임을 데이터베이스에 밀어 넣으면이 문제를 피할 수 있습니다 (UPDATE hitcounter SET hitcount = hitcount + 1;). 나는 ActiveRecord가 이것에 대한 지원을 가지고 있다고 믿는다, 나는 그것을 할 것이다. 업데이트 : 오, 이런, 네,이 작업을 수행하려면 increment_counter 메서드를 사용하고 싶습니다. Reference/Documentation.

일단 프로세스 밀어 넣기 책임을 데이터베이스로 업데이트하면 잠시 동안 성능에 대해 걱정하지 않아도됩니다. 한때 요청 당 한 번 PHP 응용 프로그램을 만들었고 100 개 이상의 업데이트/초 (똑같은 컴퓨터에서 mysqld, 지속적인 연결이없고 항상 < 10 % cpu)로 영광을 돌려주었습니다.

+0

매우 도움이되는 응답에 감사드립니다. 그것은 많은 사람들을 도와야합니다. 그래서 nmy take-away를 사용하는 이유는 increment_counter를 dbase 계층으로 밀어 넣는 것입니다. 그래서 다중 인스턴스 환경에서 (저는 heroku에 있습니다) 동시에 다른 인스턴스를 관리합니다. 감사! – jpwynn

관련 문제