Rails中的lock+sidekiq搭配技巧
透過Rails的 ApplicationRecord.transaction do 技巧,一次性交易,讓程式穩定性有助於提升。ApplicationRecord.transaction do
是 Ruby on Rails 中用來進行資料庫事務管理的一個重要方法。它的作用是將一組資料庫操作包裹在一個原子性的交易(transaction)內,確保這些操作要麼全部成功,要麼全部失敗回滾,從而保證資料的一致性和完整性。
Step1 設置 .lock鎖 + transaction
ApplicationRecord.transaction do # ... end
Lock鎖的種類:(lock! 必須在 transaction 內操作)
Rails 提供兩種作法分別為lock!
&with_lock
Ex.
# lock! 必須在 transaction 內操作
Account.transaction do
# select * from accounts where ...
account1 = accounts.find(1)
account2 = accounts.find(2)
# select * from accounts where id=? for update
account1.lock!
account2.lock!
account1.balance -= 100
account1.save!
account2.balance += 100
account2.save!
end
# with_lock 的實作其實就是幫你在外面包一層 transaction
account = Account.first
account.with_lock do
# This block is called within a transaction,
# account is already locked.
account.balance -= 100
account.save!
end
Step2 搭配 sidekiq
.lock 要能搭配 sidekiq或排程系統才能發揮效果。
這篇不會講sidekiq怎麼寫,主要概念就是當你把資料 .lock之後,
設計排程去執行這個鎖住的資料進行資料更新或建立,
避免一瞬間同時資料的寫入造成的問題。