新聞中心
并發(fā)數(shù)據(jù)庫中丟失修改問題的解決措施是本文我們主要要介紹的內容,接下來我們就從一個簡單的例子開始介紹這部分內容,希望能夠對您有所幫助。

我們注重客戶提出的每個要求,我們充分考慮每一個細節(jié),我們積極的做好成都網(wǎng)站制作、做網(wǎng)站服務,我們努力開拓更好的視野,通過不懈的努力,創(chuàng)新互聯(lián)公司贏得了業(yè)內的良好聲譽,這一切,也不斷的激勵著我們更好的服務客戶。 主要業(yè)務:網(wǎng)站建設,網(wǎng)站制作,網(wǎng)站設計,成都微信小程序,網(wǎng)站開發(fā),技術開發(fā)實力,DIV+CSS,PHP及ASP,ASP.Net,SQL數(shù)據(jù)庫的技術開發(fā)工程師。
1.問題定義
先從一個較簡單的例子為例,如火車售票系統(tǒng),數(shù)據(jù)庫表(車次,剩余票數(shù)),一個售票事務的處理過程如下:
(1) 查詢該車次剩余票數(shù)x=16。
(2) x = x – 1,得x=15
(3) 將x=15寫回該車次剩余票數(shù)。
這樣一個事務在串行運行的數(shù)據(jù)庫系統(tǒng)中是沒有問題的,如果兩個事務串行運行,各售一張票,最終結果為14。但如果在并行系統(tǒng)中,可能會有兩個售票事務實例同時執(zhí)行,由于CPU分時間片輪流執(zhí)行事務,這時有可能發(fā)生如下情況(執(zhí)行次序自上而下,兩個事務交叉運行):
售票事務T1 售票事務T2
(1) 查詢剩余票數(shù)x=16
(2) 查詢剩余票數(shù)x=16
(3) x=x-1,得x=15
(4) 將x=15寫回數(shù)據(jù)庫。
(5) x=x-1,得x=15
(6) 將x=15寫回數(shù)據(jù)庫。
即T1先查詢出了剩余票數(shù)16,此時它把控制權交給CPU,等待分配下一個時間片執(zhí)行。然后T2獲得了執(zhí)行權,查出票數(shù)依然是16。然后T1和T2不管如何輪換執(zhí)行,售出一張票后(售多張票是類似的),都將得到結果15。那么后一個事務提交的數(shù)據(jù)就覆蓋了前一個事務的數(shù)據(jù),最終結果是15,這就是所謂的丟失修改問題。
這個問題在分布式數(shù)據(jù)庫中具有一般性,其它的例子如申請手機號時,兩個用戶同時申請同一個手機號的問題,本文中我們給出這類問題的一個通用解決方案。(火車售票例子太簡單,還是比較容易解決的,沒必要用本文所述的一般性的方法,呵呵)。
2.思路
我們可以采用一個時間戳字段記錄哪個事務先修改的記錄。時間戳不是一個時間,而類似于一個自動增長字段,但它有一個特點,就是每次更新某條記錄時,會自動更新為一個新的時間戳數(shù)據(jù)。在SQL Server中,設置為一個字段為timestamp數(shù)據(jù)類型,讀取時可以使用varbinary類型讀取。
主要思路是:讀取剩余票數(shù)時就同時讀取該記錄的時間戳,當更新記錄時,判斷時間戳是否與原來讀取的相同,如果不同,說明已經有一個事務修改了這條記錄,就讓當前事務失敗。
這樣我們把數(shù)據(jù)庫表修改為:車次表(車次,剩余票數(shù),修改時間)。注意修改時間字段設置為timestamp類型,不允許為空,這樣初始化時就先自動生成了一個時間戳。
3.解決方案
售票的存儲過程:
- Create Procedure Sale
- (@Serial varchar(10), -- 車次
- @SaleCount int -- 所售票數(shù)
- ) As
- -- 取出剩余票數(shù)
- Declare @RealCount int, -- 剩余票數(shù)
- @Time varbinary(6) -- 時間戳
- Select @RealCount=剩余票數(shù), @Time=修改時間 From 車次表 Where 車次=@Serial
- -- 判斷票數(shù)是否夠
- If (@SaleCount > @RealCount)
- Begin
- Print ‘票數(shù)不夠’
- return
- End
- -- 更新數(shù)據(jù)
- Declare @RowsCount int -- 更新時影響的行數(shù)
- Update 車次表 Set 剩余票數(shù)=剩余票數(shù)-@SaleCount
- Where 車次=@Serial and 修改時間=@Time
- Set @RowsCount=@@RowsCount
- /* @@RowsCount記錄了修改最近一條SQL語句影響的行數(shù),如果為1,表示修改成功,如果為0,表示未修改任何行,出現(xiàn)這種情況的原因就是其它事務已經修改了這條記錄,造成修改時間這個自動的值變化了 */
- -- 判斷結果
- If (@RowsCount = 0)
- Print ‘事務并發(fā)造成的修改失敗’
- Else
- Print ‘售票成功
- Go
4.測試
測試時我們創(chuàng)建另外一個售票的存儲過程SaleDelay,與上面的Sale存儲過程不同的是,在取出票數(shù)之后增加一個延時語句,比如延時10秒。
Waitfor Delay ‘0:0:10’
先啟動SaleDelay,然后快速啟動Sale,這樣SaleDelay因為讀取后10s才去寫數(shù)據(jù),這期間Sale已經寫入了數(shù)據(jù),SaleDelay會失敗。
測試技巧:在查詢分析器中打開兩個窗口,***選用橫向平鋪讓兩個窗口都顯示出來。兩個窗口分別輸入exec SaleDelay ‘車次x’ 1和exec Sale '車次x’ 1,注意兩個車次號要相同。先點擊***個窗口,然后點執(zhí)行;然后迅速點第二個窗口,點執(zhí)行,等待執(zhí)行結果。
關于并發(fā)數(shù)據(jù)庫中丟失修改問題的解決措施的相關知識就介紹到這里了,希望本次的介紹能夠對您有所收獲!
新聞標題:并發(fā)數(shù)據(jù)庫中丟失修改問題的解決措施詳解
網(wǎng)站路徑:http://fisionsoft.com.cn/article/dhjhipj.html


咨詢
建站咨詢
