2011-03-10 7 views
1

내 사용자 모델에는 다음과 같은 문자가 있습니다 :heroku에서 validates_uniqueness_of가 실패 했습니까?

validates_uniqueness_of : fb_uid (facebook connect를 사용하고 있습니다).

그러나 사용자 가입시 중복 행이 나타납니다. 이건 정말 나빠.

두 레코드의 생성 시간은 100ms 내에 있습니다. 나는 그것이 두 개의 분리 요청에서 발생하는지 아닌지를 결정할 수 없었습니다 (heroku 로깅은 실패하고 단지 지금까지만 돌아 왔고 두 번만 발생했습니다).

두 가지 : 나는 이름 정보, 친구, 사진에 대한 FB API를 쿼리 때문에

  • 때때로 요청은 약간의 시간이 소요됩니다.
  • 저는 bigint를 사용하여 fb_uid를 저장하고 있습니다 (백엔드는 포스트 그레스입니다).

dev에 복제 할 수 없었습니다.

모든 아이디어는 극명하게 평가 될 것입니다.

def self.create_from_cookie(fb_cookie, remote_ip = nil) 
    return nil unless fb_cookie 
    return nil unless fb_hash = authenticate_cookie(fb_cookie) 
    uid = fb_hash["uid"].join.to_i 

    #Make user and set data 
    fb_user = FacebookUser.new 
    fb_user.fb_uid = uid 
    fb_user.fb_authorized = true 
    fb_user.email_confirmed = true 
    fb_user.creation_ip = remote_ip 
    fb_name_data, fb_friends_data, fb_photo_data, fb_photo_ext = fb_user.query_data(fb_hash) 
    return nil unless fb_name_data 
    fb_user.set_name(fb_name_data) 
    fb_user.set_photo(fb_photo_data, fb_photo_ext) 

    #Save user and friends to the db 
    return nil unless fb_user.save 
    fb_user.set_friends(fb_friends_data) 
    return fb_user 
end 
+0

가입 기능을 게시 할 수 있습니까? – Spyros

+0

은 (는) 질문에 게시했습니다 – Brian

답변

1

내가 연결 페이스 북에 정말 잘 알고 모르겠지만, 두 개의 별도의 계정에서 두 개의 별도의 사용자가 매우 빠르게 연속 요청을 게시 할 경우 같은 UUID 두 가지를 얻을 수입니다 로그인의 기능 요청이 완료되기 전에? validates_uniqueness_of은 여전히 ​​경쟁 조건의 이러한 종류의에서 고통을 수 있습니다 (그렇지 않으면 경쟁 조건이라고도 함) 자세한 내용은 여기에서 찾을 수 있습니다 :이 검사는 데이터베이스 외부 를 수행

http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates_uniqueness_of

때문에 여전히 있다 중복 값이 ​​두 개의 병렬 트랜잭션에 삽입 된 이 될 가능성이 있습니다. 이 문제를 방지하려면 필드에 고유 한 인덱스를 만들어야합니다. 자세한 내용은 add_index를 참조하십시오.

실제로 데이터베이스 제약 조건을 추가하여이를 수행 할 수 있습니다. 이제 사용자가 대신 일반적으로 디버깅이 데이터베이스에서 불법 데이터를 생성하는 것이 바람직하다 요청을 완료 할 수있는의 오류가 발생하는 것입니다

add_index :user, :fb_uid, :unique => true 

을 : 실행 한 후 데이터베이스 마이그레이션이를 추가하고 수동으로 청소하십시오.

+0

하! 엄청 고마워. 필자는 fb_uid 색인에 그 제약을 추가 할 것이다. – Brian

0

루비 온 레일즈 v3.0부터.5 모듈 액티브 ::하는 검증 :: ClassMethods http://s831.us/dK6mFQ

동시성과 무결성

액티브와 함께이 [validates_uniqueness_of] 검증 방법을 사용하여 :: 자료 번호는 저장하지 부재 을 보장하는 것은 아닙니다 중복의 레코드 삽입, 고유성 때문에 응용 프로그램 수준에서 확인 는 본질적으로 경쟁 조건이 발생하기 쉬운입니다. 예를 들어, 두 명의 사용자가 동일한 시간에 댓글을 게시하려고 시도하고 댓글의 제목이 고유해야한다고 가정합니다.

0

... 코드 내부 경쟁 조건의 어떤 종류가있는 것 같습니다 : 데이터베이스 수준에서 이러한 사용자가 수행하는 조치는 다음 방식으로 인터리브 될 수 있습니다. 이를 확인하기 위해 먼저 코드를 변경하여 facebook 값을 먼저 추출한 다음 새 facebook 객체를 작성합니다.

그렇다면 함수가 실행되는지 여부를 확인하기위한 테스트를 작성하는 것이 좋습니다. 그것은 두 번 실행 된 것 같습니다.

그리고 이에 따라 페이스 북의 결과를 기다리는 동안 경쟁 조건이있는 것으로 보입니다.

관련 문제