2017-02-17 71 views
1

我已經得到了跨越某些表提交一些數據的一些客戶端代碼,簡單來說就像這樣:如何在更新後立即獲取時間戳值?

  • 客戶端[ID,平衡,時間戳]
  • ClientAssets [ID,由assetid,數量]
  • ClientLog [ID,客戶端Id,BalanceBefore,BalanceAfter]

當客戶購買的資產,我做了下面的僞代碼:

初學者ñ交易

  1. GetClientRow其中id = 1
  2. 擁有新資產的成本餘額不足?是...
  3. 插入到客戶資產...
  4. UpdateClient - >更新客戶端設置餘額= f_SumAssetsForClient(1)WHERE ID = 1和時間戳= TS從步驟1;
  5. GetClientRow當ID = 1
  6. 插入進ClientLog BalanceBefore =餘額在步驟1中,BalanceAfter =餘額在步驟5. COMMIT

在步驟4中,客戶端行中1個更新語句中使用更新的一個函數'f_SumAssetsForClient',它爲客戶端彙總資產並返回這些資產的餘額。同樣在第4步,時間戳會自動更新。

我的問題是,當我在第5步再次調用GetClientRow時,有人可能更新了客戶端餘額,所以當我在步驟6中寫入日誌時,它不是真正的這一套步驟後的平衡。這將是這筆交易之外的另一筆寫款之後的餘額。

如果我在步驟4中調用UPDATE時可以從客戶端行獲取新更新的時間戳,那麼我可以通過此步驟僅抓取客戶端行,其中TS =新更新的TS。這可能嗎?或者是我的設計有缺陷。我無法找到解決步驟5和步驟6之間的陳舊數據問題的方法。我覺得在表格設計中存在問題,但無法完全看到它。

+1

聽起來像你需要一個步驟3。5那就是'選擇f_SumAssetsForClient(1)'然後存儲該值,然後進行更新,然後寫日誌的價值觀 - 你不應該有在所有處理時間戳 - 或做全過程作爲存儲過程 –

+0

@MichaelCoxon哦,現在總是有意義的。基本上,在步驟4之後的任何時候,數據讀取都是不可信的。但如果我在最終的UPDATE之前獲取所有的值,這些值由時間戳檢查保護,並確定提交或回滾,並使用它們來構建報告,那麼它應該沒問題。謝謝 :)。 –

+1

那麼,你在一個事務中運行這些語句,所以常用的方法是將第一選擇中的鎖升級到WRITE鎖(似乎是MySQL中的SELECT ... FOR UPDATE),這會阻止其他會話從修改這個ID。 – dnoeth

回答

1

步驟1需要是SELECT ... FOR UPDATE。任何其他需要更改的數據也需要「鎖定」FOR UPDATE

這樣,另一個線程不能潛入並修改這些行。他們可能會被推遲到COMMITted之後,或者可能會出現死鎖。無論哪種方式,你擔心的事情都不會發生。沒有時間戳遊戲。

+0

是的,我將不得不改變我的答案,因爲這是我最終使用和什麼似乎最正確的。我最初的問題表明,我正在處理一個像數據結構的樹/圖,SELECT ... FOR UPDATE專門用於處理這種數據模型。 –

1

從評論複製

聽起來像是你需要逐步3.5是SELECT f_SumAssetsForClient(1)然後 商店值,然後進行更新,然後寫日誌的價值觀 - 你 不應該有應對帶有時間標記在所有 - 或做整個過程作爲 一個存儲過程

相關問題