自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

并發(fā)數(shù)據(jù)庫(kù)中丟失修改問(wèn)題的解決措施詳解

數(shù)據(jù)庫(kù) SQL Server
本文我們以火車售票系統(tǒng)為例介紹了并發(fā)數(shù)據(jù)庫(kù)中丟失修改問(wèn)題的解決思路以及解決措施,希望能夠?qū)δ兴鶐椭?/div>

并發(fā)數(shù)據(jù)庫(kù)丟失修改問(wèn)題的解決措施是本文我們主要要介紹的內(nèi)容,接下來(lái)我們就從一個(gè)簡(jiǎn)單的例子開始介紹這部分內(nèi)容,希望能夠?qū)δ兴鶐椭?/p>

1.問(wèn)題定義

先從一個(gè)較簡(jiǎn)單的例子為例,如火車售票系統(tǒng),數(shù)據(jù)庫(kù)表(車次,剩余票數(shù)),一個(gè)售票事務(wù)的處理過(guò)程如下:

(1) 查詢?cè)撥嚧问S嗥睌?shù)x=16。

(2) x = x – 1,得x=15

(3) 將x=15寫回該車次剩余票數(shù)。

這樣一個(gè)事務(wù)在串行運(yùn)行的數(shù)據(jù)庫(kù)系統(tǒng)中是沒(méi)有問(wèn)題的,如果兩個(gè)事務(wù)串行運(yùn)行,各售一張票,最終結(jié)果為14。但如果在并行系統(tǒng)中,可能會(huì)有兩個(gè)售票事務(wù)實(shí)例同時(shí)執(zhí)行,由于CPU分時(shí)間片輪流執(zhí)行事務(wù),這時(shí)有可能發(fā)生如下情況(執(zhí)行次序自上而下,兩個(gè)事務(wù)交叉運(yùn)行):

售票事務(wù)T1 售票事務(wù)T2

(1) 查詢剩余票數(shù)x=16

(2) 查詢剩余票數(shù)x=16

(3) x=x-1,得x=15

(4) 將x=15寫回?cái)?shù)據(jù)庫(kù)。

(5) x=x-1,得x=15

(6) 將x=15寫回?cái)?shù)據(jù)庫(kù)。

即T1先查詢出了剩余票數(shù)16,此時(shí)它把控制權(quán)交給CPU,等待分配下一個(gè)時(shí)間片執(zhí)行。然后T2獲得了執(zhí)行權(quán),查出票數(shù)依然是16。然后T1和T2不管如何輪換執(zhí)行,售出一張票后(售多張票是類似的),都將得到結(jié)果15。那么后一個(gè)事務(wù)提交的數(shù)據(jù)就覆蓋了前一個(gè)事務(wù)的數(shù)據(jù),最終結(jié)果是15,這就是所謂的丟失修改問(wèn)題。

這個(gè)問(wèn)題在分布式數(shù)據(jù)庫(kù)中具有一般性,其它的例子如申請(qǐng)手機(jī)號(hào)時(shí),兩個(gè)用戶同時(shí)申請(qǐng)同一個(gè)手機(jī)號(hào)的問(wèn)題,本文中我們給出這類問(wèn)題的一個(gè)通用解決方案。(火車售票例子太簡(jiǎn)單,還是比較容易解決的,沒(méi)必要用本文所述的一般性的方法,呵呵)。

2.思路

我們可以采用一個(gè)時(shí)間戳字段記錄哪個(gè)事務(wù)先修改的記錄。時(shí)間戳不是一個(gè)時(shí)間,而類似于一個(gè)自動(dòng)增長(zhǎng)字段,但它有一個(gè)特點(diǎn),就是每次更新某條記錄時(shí),會(huì)自動(dòng)更新為一個(gè)新的時(shí)間戳數(shù)據(jù)。在SQL Server中,設(shè)置為一個(gè)字段為timestamp數(shù)據(jù)類型,讀取時(shí)可以使用varbinary類型讀取。

主要思路是:讀取剩余票數(shù)時(shí)就同時(shí)讀取該記錄的時(shí)間戳,當(dāng)更新記錄時(shí),判斷時(shí)間戳是否與原來(lái)讀取的相同,如果不同,說(shuō)明已經(jīng)有一個(gè)事務(wù)修改了這條記錄,就讓當(dāng)前事務(wù)失敗。

這樣我們把數(shù)據(jù)庫(kù)表修改為:車次表(車次,剩余票數(shù),修改時(shí)間)。注意修改時(shí)間字段設(shè)置為timestamp類型,不允許為空,這樣初始化時(shí)就先自動(dòng)生成了一個(gè)時(shí)間戳。

3.解決方案

售票的存儲(chǔ)過(guò)程:

 

  1. Create Procedure Sale  
  2.  
  3. (@Serial varchar(10), -- 車次  
  4.  
  5. @SaleCount int -- 所售票數(shù)  
  6.  
  7. ) As  
  8.  
  9. -- 取出剩余票數(shù)  
  10.  
  11. Declare @RealCount int, -- 剩余票數(shù)  
  12.  
  13. @Time varbinary(6) -- 時(shí)間戳  
  14.  
  15. Select @RealCount=剩余票數(shù), @Time=修改時(shí)間 From 車次表 Where 車次=@Serial  
  16.  
  17. -- 判斷票數(shù)是否夠  
  18.  
  19. If (@SaleCount > @RealCount)  
  20.  
  21. Begin  
  22.  
  23. Print ‘票數(shù)不夠’  
  24.  
  25. return  
  26.  
  27. End  
  28.  
  29. -- 更新數(shù)據(jù)  
  30.  
  31. Declare @RowsCount int -- 更新時(shí)影響的行數(shù)  
  32.  
  33. Update 車次表 Set 剩余票數(shù)=剩余票數(shù)-@SaleCount  
  34.  
  35. Where 車次=@Serial and 修改時(shí)間=@Time  
  36.  
  37. Set @RowsCount=@@RowsCount  
  38.  
  39. /* @@RowsCount記錄了修改最近一條SQL語(yǔ)句影響的行數(shù),如果為1,表示修改成功,如果為0,表示未修改任何行,出現(xiàn)這種情況的原因就是其它事務(wù)已經(jīng)修改了這條記錄,造成修改時(shí)間這個(gè)自動(dòng)的值變化了 */  
  40.  
  41. -- 判斷結(jié)果  
  42.  
  43. If (@RowsCount = 0)  
  44.  
  45. Print ‘事務(wù)并發(fā)造成的修改失敗’  
  46.  
  47. Else  
  48.  
  49. Print ‘售票成功  
  50.  
  51. Go 

 

4.測(cè)試

測(cè)試時(shí)我們創(chuàng)建另外一個(gè)售票的存儲(chǔ)過(guò)程SaleDelay,與上面的Sale存儲(chǔ)過(guò)程不同的是,在取出票數(shù)之后增加一個(gè)延時(shí)語(yǔ)句,比如延時(shí)10秒。

Waitfor Delay ‘0:0:10’

先啟動(dòng)SaleDelay,然后快速啟動(dòng)Sale,這樣SaleDelay因?yàn)樽x取后10s才去寫數(shù)據(jù),這期間Sale已經(jīng)寫入了數(shù)據(jù),SaleDelay會(huì)失敗。

測(cè)試技巧:在查詢分析器中打開兩個(gè)窗口,***選用橫向平鋪?zhàn)寖蓚€(gè)窗口都顯示出來(lái)。兩個(gè)窗口分別輸入exec SaleDelay ‘車次x’ 1和exec Sale '車次x’ 1,注意兩個(gè)車次號(hào)要相同。先點(diǎn)擊***個(gè)窗口,然后點(diǎn)執(zhí)行;然后迅速點(diǎn)第二個(gè)窗口,點(diǎn)執(zhí)行,等待執(zhí)行結(jié)果。

關(guān)于并發(fā)數(shù)據(jù)庫(kù)中丟失修改問(wèn)題的解決措施的相關(guān)知識(shí)就介紹到這里了,希望本次的介紹能夠?qū)δ兴斋@!

【編輯推薦】

  1. 初學(xué)SQL Server數(shù)據(jù)庫(kù)的一些常用操作總結(jié)
  2. 初學(xué)SQL Server筆記之修改表結(jié)構(gòu)的示例代碼
  3. SQL Server批量修改字段的數(shù)據(jù)類型的代碼實(shí)例
  4. SQL Server數(shù)據(jù)庫(kù)字段說(shuō)明的添加修改刪除示例
  5. SQL Server 2005數(shù)據(jù)庫(kù)中設(shè)置自動(dòng)編號(hào)字段實(shí)例解析

 

責(zé)任編輯:趙鵬 來(lái)源: CSDN博客
相關(guān)推薦

2024-05-08 08:14:18

數(shù)據(jù)庫(kù)IO備份

2010-07-06 14:40:15

解決SQL Serve

2011-05-24 10:26:12

Oracle數(shù)據(jù)庫(kù)日志文件

2010-04-21 12:13:44

Oracle數(shù)據(jù)庫(kù)

2011-07-28 16:39:03

MySQL數(shù)據(jù)庫(kù)修改MySQL密碼

2011-07-18 09:36:42

Mysql數(shù)據(jù)庫(kù)root@localh

2011-05-26 09:46:21

Oracle數(shù)據(jù)庫(kù)安全

2009-11-04 12:37:32

ADO.NET SQL

2024-12-16 00:52:26

MySQL數(shù)據(jù)庫(kù)并發(fā)

2011-04-07 09:06:27

MySQL數(shù)據(jù)庫(kù)密碼

2010-07-08 11:05:14

SQL Server數(shù)

2010-07-05 14:41:21

SQL Server數(shù)

2018-07-30 15:00:05

數(shù)據(jù)庫(kù)MySQLJOIN

2010-09-08 16:03:57

SQL臨時(shí)表數(shù)據(jù)庫(kù)

2010-08-18 11:11:36

路由器報(bào)文

2025-01-02 08:00:00

SQL數(shù)據(jù)庫(kù)恢復(fù)階段

2020-03-27 16:05:49

數(shù)據(jù)庫(kù)數(shù)據(jù)MySQL

2010-05-11 12:57:45

MySQL數(shù)據(jù)庫(kù)編碼

2010-04-12 16:43:59

Oracle數(shù)據(jù)庫(kù)

2011-07-06 14:09:40

ASP
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)