在我的Rails應用程序中,我有一些像這樣的代碼:如何鎖定一組操作對象?
def foo
if object_bar_exists
raise "can't create bar twice!"
end
Bar.create
end
這可以通過進入應用服務器的兩個不同的請求來調用。如果此代碼由兩個請求同時運行,並且它們都同時運行if
檢查,則既不會發現另一個的bar
,也不會創建2個bar
。
爲「酒吧的集合」創建「互斥」的最佳方式是什麼?數據庫中的特殊目的互斥表?
更新
我要強調的是,我不能在這裏使用一個內存互斥的,因爲併發是跨請求/過程,而不是線程。
我認爲事務只能確保它們內部的一切都是自動執行的。不能同時使用兩個進程運行相同的事務代碼,並且有相同的問題? (最初的'if'檢查並行運行並且成功,然後寫入並行發生,並且在兩種情況下所有相應的代碼都以原子方式發生) – 2011-03-24 20:03:53
如果鎖定該行,則不會。這是數據庫中的行級鎖定,因此另一個事務無法訪問它。此外,如果您有確保唯一行的驗證錯誤,則第一次寫入將成功,下一次將失敗並回滾整個事務。 – 2011-03-24 22:16:09
您確實希望事務**和**數據庫中的唯一索引來強制解決問題。當事情出錯時,交易將保持一切清潔,唯一的索引會在事情出錯時告訴你。 – 2011-03-24 22:18:51