0
我有幾個同一個實體(用戶)的Resque worker。成功處理後,應該減少call_left
屬性。ActiveJob/Resque髒讀。事務隔離級別
它與perform_now
(因此)完美地工作,但與perform_later
(並行)產生不可預知的結果。在日誌中有相同數量的提交calls_left
。
我試圖用reload
方法甚至設置最高的隔離級別。但仍然有這個問題。
如何解決?
class DataProcessJob < ActiveJob::Base
queue_as :default
def perform(user_id, profile_id)
User.transaction(isolation: :serializable) do
user = User.find(user_id).reload
user.data_process(profile_id)
user.update(calls_left: user.calls_left-1)
end
end
end
鎖不起作用。樂觀的人不能工作,因爲它被設計爲在單一過程中工作。悲觀的 - 只是沒有。 原始SQL似乎工作,謝謝。 –
實際上,Rails通過向表中添加'lock_version'字段來實現樂觀鎖定(與數據庫級別樂觀鎖定略有不同)。因此,如果它們在SQL更新查詢中檢查鎖定版本,它將在非單一過程方案中起作用。但是,我不確定,沒有查看源代碼。你嘗試過使用樂觀鎖嗎?如果你這樣做,它不起作用,請讓我知道。今後注意這一點很好。 – Uzbekjon
樂觀鎖定默認打開。如果對象已過時,它會引發'搶救ActiveRecord :: StaleObjectError',在我的情況中不是這樣。 這是來自文檔: '這個鎖定機制將在單個Ruby進程中運行。爲了使其適用於所有Web請求,推薦的方法是將lock_version作爲隱藏字段添加到您的表單中 –