2011-08-07 20 views
0

如果2個用戶連接到Access並運行檢查最後一個號碼的查詢,請增加此號碼並向數據庫中插入一條記錄。當2個用戶嘗試連接時,誰會優先訪問?

誰獲得優先權?

爲什麼我會看到兩個具有相同編號的重複記錄?

+0

我假設你在談論一個MS Access數據庫? – CodesInChaos

+0

我假設你的三個操作的組合不是原子的。使用事務是古典的解決方案,但我不確定訪問是否支持這一點。因此,假設每個用戶都在同一臺機器上運行,您可以在C#中使用鎖定來獲得原子性。 – CodesInChaos

回答

1

他們都沒有得到「優先」。當您談論非原子操作時,這不再是一個有用的術語。一個例子將在這裏說明這個問題。

這是你的腳本如下:

  • 從數據庫中讀取值。
  • 遞增1.
  • 將新值寫入數據庫。

這適用於一次只有一個人使用數據庫的情況。如果有多人蔘與,事情就不會起作用。以下是現在發生的事情:

  • DB中的原始值是「100」。
  • 客戶端A讀取「100」。
  • 客戶端A本地增加「100」到「101」,但尚未寫入。
  • 客戶端B讀取「100」。
  • 客戶端B在本地增加「100」到「101」,但尚未寫入。
  • 客戶端A寫入「101」。
  • 客戶端B寫入「101」。

這就是所謂的競態條件,這是因爲你沒有使用transaction。通過交易,以下是可能發生的情況:

  • DB中的原始值爲「100」。
  • 客戶端A以此值開始交易。
  • 客戶端A讀取「100」。
  • 客戶端A本地增加「100」到「101」,但尚未寫入。
  • 客戶端B嘗試開始一個事務,但已經有一個掛起的事務,所以它還不能啓動。
  • 客戶端A寫入「101」。
  • 客戶端A關閉交易並實際寫入值。
  • 客戶端B以此值開始交易。
  • 客戶端B讀取「101」。
  • 客戶端B本地增加「101」到「102」,但尚未寫入。
  • 客戶端B寫入「102」。
  • 客戶端B關閉事務並且實際寫入值。
+0

感謝您的幫助,我可以得到怎樣,如果你想找到交易(提交/回滾)信息使用事務在訪問 – Gali

+0

閱讀該死的幫助文件樣本。 –

2

這是一個併發問題:

兩個用戶A和B從數據庫中讀取的當前值。然後A在客戶端增加它並將其寫回數據庫,但B已經讀取了該值並且不知道遞增的值。與之前的A相同,B增加值並將其寫回,並用相同的數字覆蓋A的變化。

這種獨特的數代的是不是安全。您應該讓數據庫通過使用自動增量值來執行增量操作。

或者你可以有下面的結構:

  • 創建一個額外的ID表。
  • 創建一個存儲過程中,你
    • 鎖訪問ID表
    • 讀取當前值
    • 增量,並將其寫回
    • 解鎖訪問
    • 返回增加後的值

創建ID表可以防止鎖定您的數據表。

0

那麼,從你問題中的最後一個問題來看,你看到兩個重複數字記錄的原因是因爲你允許在你的模式/數據庫/表設計中開始。首先在數據庫中添加約束和關係,並且您的方案會拋出一個錯誤,您可以使用開放式客戶端的開放式併發和/或繼續進行數據庫端的唯一密鑰生成和/或使用事務和等等。

0

這是一個Access經常被問到的問題。如果你在谷歌的「訪問多用戶自定義計數器」,你會得到很多解決方案。

它們通常基於使用表來保存「種子」值,該值僅被編輯,以便一次只有一個用戶可以更改該種子值。可能有其他方法使用Jet/ACE交易,但這種方法要簡單得多。

請注意,來自MS的三個解決方案中的兩個解決方案使用ADO,這在Access中不可取,但可能適用於外部Access。

相關問題