Rails- 사용자가 동시에 동일한 데이터를 동시에 편집하는 것을 방지하기 위해 간단한 잠금을 구현합니다.

StackOverflow https://stackoverflow.com/questions/1803574

문제

다른 사용자가 편집하는 동안 사용자가 데이터를 편집하는 것을 방지 해야하는 앱이 있습니다. 나는 그것을하는 가장 좋은 방법을 생각하려고 노력하고 있으며 아이디어를 요청하고 싶었습니다. 지금까지 키/값 쌍의 DB에 응용 프로그램을 광범위하게 구성하는 설정 모델을 만들었습니다. 따라서 잠금의 경우 Locked_table_uid라고 불리는 설정 인스턴스가 있으며 테이블이 무료 인 경우 테이블 또는 NULL (NUL)을 편집하는 사용자의 user_id를 저장했습니다.

>> lock = Setting.find_by_key('LOCKED_TABLE_UID')

그런 다음 애플리케이션 컨트롤러에서 잠금을 획득하고 해제하기 위해 2 가지 방법을 구현했습니다.

# current_user returns the user currently logged in
def acquire_lock
  lock = Setting.find_by_key("LOCKED_TABLE_UID")
  if lock.value
    # if lock taken, see if it's the current_user or someone else
    if lock.value.to_i == current_user.id.to_i
      return true
    else
      return false
    end
  else
    # lock is free, assign it to this user
    lock.value = current_user.id
    return true if lock.save
  end
end

def release_lock
  lock = Setting.find_by_key("LOCKED_TABLE_UID")
  if lock.value
    # the lock belongs to current_user, so he can release it
    if lock.value.to_i == current_user.id.to_i
      lock.value = nil
      return true if lock.save
    else
      # not your lock, go away
      return false
    end
  else
    # lock is free, quit bugging
    return true
  end
end

내가 원하는 것은 잠금 메커니즘을 포함하는 일종의 블록 코드를 만드는 것입니다.

def some_crud_action
  requires_locking do |lock|
    if lock
      # do some CRUD stuff here
    else
      # decline CRUD and give some error
    end
  end
end

나는 이것에 대한 도움을 주셔서 감사합니다 - 그러나 나는 또한 모든 것을 성취하는 방법이나 내가 간과했을 수도있는 것들에 대한 다른 제안에도 열려 있습니다. 이 자물쇠는 원자 일 필요는 없지만 상당히 기본적이고 가장 중요합니다.

도움이 되었습니까?

해결책

당신은 거의 거기에 있습니다. require_locking을 만드시겠습니까? 적합한 행동. 그런 다음 prever_filter로 처리하십시오.

 before_filter :requires_locking?, :only => [:update, :destroy]
 after_filter :release_lock, :only => [:update, :destroy]

 def requires_locking do |lock|
   unless acquire_lock
      lock = Setting.find_by_key("LOCKED_TABLE_UID")
      user_with_lock = User.find(lock.value)
      flash[:message] = "Action denied: Table locked by: #{user_with_lock.name}"
      redirect_to :back
   end
 end

다른 팁

ActiveRecord 내장 잠금 기능을 보셨습니까?

나는 아이디어가 마음에 들지만 솔루션에 큰 문제가 있으며, 전체 테이블의 자물쇠를 얻고 공개하고 있다는 것입니다.

괜찮을 수있는 매우 작은 앱의 경우, 수천 명의 사용자가 '제품'테이블에 액세스하려고하고 누군가가 자신의 제품과 완전히 관련이없는 항목을 편집하고 있기 때문에 기다려야한다고 상상해보십시오.

어쩌면 당신은 더 미세한 곡물 접근 방식을 가질 수 있고 테이블 대신 특정 행을 잠글 수 있습니다. 잠금에는 테이블 이름, 행 ID 및 사용자 ID가 포함됩니다.

제 생각에는 acts_as_lockable_by GEM은 더 간단한 용어로 요청한 작업을 정확히하고 코드가 적습니다. 레일이나 베어 루비 프로젝트와 쉽게 통합 할 수 있습니다.

이 보석으로 원자력을 얻습니다 lock, unlock 그리고 renew_lock 행동 양식. 또한 자동 만료를받습니다 ttl 잠금 장치, 똥이 팬에 부딪 치면 리소스를 잠금 해제 할 수 없으면 자동으로 잠금 해제됩니다!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top