Rails應(yīng)用程序中同時(shí)修改操作沖突問題的解決方案
Rails 應(yīng)用程序中操作沖突是一個(gè)常見問題,Rails 提供了簡(jiǎn)單有效的解決方法。
舉一個(gè)實(shí)際的例子:我們的系統(tǒng)里有一個(gè)商店模塊,商店中重要的一塊是對(duì)產(chǎn)品信息的管理,比如運(yùn)營(yíng)人員常常會(huì)編輯產(chǎn)品的信息,包括產(chǎn)品標(biāo)題,營(yíng)銷口號(hào)和價(jià)格等等。因?yàn)樾薷氖诸l繁,碰巧同時(shí)編輯提交修改的話,就會(huì)偶爾遇到修改丟失的問題,運(yùn)營(yíng)人員 A 修改產(chǎn)品標(biāo)題,運(yùn)營(yíng)人員 B 修改價(jià)格,A 和 B 提交修改都提示修改成功,但是結(jié)果上只是 A 的修改結(jié)果生效,B 的修改被 A 的修改沖掉了。
仔細(xì)研究原因,發(fā)現(xiàn)是因?yàn)樾薷墓δ苋鄙俨僮鳑_突機(jī)制,而修改操作同時(shí)發(fā)生導(dǎo)致了問題。 如下圖所示,A 和 B 同時(shí)從數(shù)據(jù)庫(kù)中查詢數(shù)據(jù),在 web 頁(yè)面中修改同樣的數(shù)據(jù),提交保存時(shí)是以 web 頁(yè)面中提交的數(shù)據(jù)為準(zhǔn),從而導(dǎo)致 A 的修改把 B 的修改給覆蓋了。
Rails 的 樂觀鎖Optimistic Locking 是解決這個(gè)問題的有力工具,它的原理是在數(shù)據(jù)庫(kù)表中增加一個(gè)字段(默認(rèn)是 lock_version,可配置)記錄數(shù)據(jù)的版本號(hào),每個(gè)提交的修改都帶上這個(gè)版本號(hào),在真正 update 修改數(shù)據(jù)之前,先判斷提交的 lock_version 數(shù)據(jù)和數(shù)據(jù)庫(kù)中的是否一致,如果不一致,則認(rèn)為發(fā)生數(shù)據(jù)沖突,將拋出 ActiveRecord::StaleObjectError 異常,這樣程序就可以捕獲這個(gè)異常,提醒用戶發(fā)生了沖突,由用戶去協(xié)調(diào)解決沖突。
相關(guān)示例代碼如下所示:
# migration: add lock_version to products
add_column :products, :lock_version, :integer, defalut: 0
# update product with StaleObjectError checking
begin
product.update(params[:product])
rescue ActiveRecord::StaleObjectError
render 'confilct'
end
相關(guān)文章
Ruby中的block、proc、lambda區(qū)別總結(jié)
這篇文章主要介紹了Ruby中的block、proc、lambda區(qū)別總結(jié),本文講解了yield 和 block call 的區(qū)別、block 和 proc、lambda 的區(qū)別、proc 和 lambda 的區(qū)別,需要的朋友可以參考下2015-03-03簡(jiǎn)單對(duì)比分析Ruby on Rails 和 Laravel
web應(yīng)用程序開發(fā)中兩個(gè)相對(duì)而言更加流行的框架是 Ruby on Rails 和 Laravel. 它們兩個(gè)都是非常成熟的項(xiàng)目,已經(jīng)面世相當(dāng)長(zhǎng)一段時(shí)間了 .2014-07-07淘寶網(wǎng)提供的國(guó)內(nèi)RubyGems鏡像簡(jiǎn)介和使用方法
由于國(guó)內(nèi)的網(wǎng)絡(luò)環(huán)境,導(dǎo)致 rubygems.org 存放在 Amazon S3 上面的資源文件間歇性連接失敗,因此使用gem或bundle時(shí)常常會(huì)遇到長(zhǎng)久無響應(yīng)的情況2014-04-04