2009-11-26 34 views
4

我有一個應用程序,我需要防止用戶在編輯數據時由其他用戶編輯數據。我試圖想到做到這一點的最佳方式,並希望徵求意見。到目前爲止,我已經創建了一個設置模型,用於存儲鍵/值對中db的應用程序範圍配置。所以,對於鎖,我有一個名爲LOCKED_TABLE_UID的設置實例,它存儲了編輯表的用戶的user_id,如果表是空的,則存儲null(nil)。rails - 實現簡單鎖定以防止用戶同時編輯相同數據

>> 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 

我很感激這方面的幫助 - 但我也接受其他建議如何完成所有這些,或者我可能忽略了一些事情。這個鎖並不一定是原子的,但相當基本和最重要的 - 它的工作原理:) 謝謝。

回答

1

你幾乎沒有。創建你的require_locking?你認爲合適的行動。然後用before_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 
7

你見過ActiveRecord內置的鎖定功能嗎?

+0

這些都不錯,但我正在尋找更簡單的東西,它也會提供用戶當前持有鎖的信息。 – sa125 2009-11-26 13:28:48

0

我喜歡這個主意,但看到你的解決方案存在一個大問題,那就是你得到並釋放整個表的鎖。

對於一個非常小的應用程序來說,這可能很好,但想象一下,如果有成千上萬的用戶試圖訪問'PRODUCTS'表並且不得不等待,因爲有人正在編輯與他們自己的產品完全無關的條目。

也許你可以有一個更細粒度的方法,並鎖定特定的行而不是表。然後鎖將包括表名,行ID和用戶ID。

相關問題