2016-11-07 40 views
3

我有一個正確的SQL解決方案的問題。SQL SUM表達式和鎖

當前狀況: 我的數據庫包含銀行交易(貸記和借記)表。

  • 信貸交易簽署爲posivitive量(+),和
  • 借記卡交易爲負值( - )。

使用DB的應用程序是一個多用戶web應用程序,因此Transactions表包含許多行,這些行引用了不同的用戶。 某些webapp操作需要使用Transactions表檢查實際餘額,並使用Transactions表保存借記交易(操作價格)。

我覺得這個機制的架構,並有一些問題:

  1. 是它來計算平衡交易的貸方和借方每次用戶請求的總和是一個好主意?我知道這可能是低效的數據庫。也許我應該在某處保存快照?

  2. 如何確保數據內聚,當一個用戶檢查「餘額」作爲信用卡/借記交易的總和,和另一個用戶在同一時間節省借記交易(因爲他/她更快)?我想到一個悲觀的鎖,但我應該鎖定什麼?我知道,與聚合(SUM)鎖可以在PostgreSQL上是不可能的(數據庫我用)。」

對不起,我的英語,我希望我的問題是可以理解的。:)

回答

1

我會考慮或者:

存放在賬戶記錄中的平衡,在天平的準確日期進行

獲取當前餘額爲自該日讀取帳戶餘額,然後包括任何交易的問題。 。

您可以重新計算計劃作業,並在午夜過後的一個小時平衡時間戳。

OR(這是我的首選解決方案):

每一個事務或批量交易的加載時間,鎖定相關的賬戶記錄,並作爲同一交易的一部分從插入的值更新它們

這具有序列化賬戶訪問權的優點,該賬戶可以幫助確定交易是否可以繼續進行,或者由於基於餘額計算的決策而進行。

1

如果你想避免在用戶賬戶中的餘額,東西,可能有更好的表現,我會嘗試的做法是:

  • 每個交易將涉及到只有一個帳戶。
  • 每筆交易在交易之後都會有賬戶餘額。

因此,該賬戶的最後交易將具有當前餘額。

例:

TransactionId | AccountId | Datetime | Ammount | Balance 
      1 |   1 | 7/11/16 |  0 |  0 
      2 |   1 | 7/11/16 |  500 |  500 
      3 |   1 | 7/11/16 |  -20 |  480 
      4 |   1 | 8/11/16 |  50 |  530 
      5 |   1 | 8/11/16 | -200 |  330 

這樣你就可以得到賬戶餘額(最後交易與帳戶ID),你將能夠提供更好的視野進入一段時間的餘額變動。

+0

謝謝。那麼按照datetime對交易進行排序是一個好主意(對於給定的AccountId),然後獲取最後的交易,然後在執行時鎖定它:檢查餘額並保存另一個交易?我的TransactionId主鍵是一個UUID,所以我不能按它排序。 Datetime精度怎麼樣?例如。幾次交易具有相同日期的情況(DD/MM/YYYY HH:mm:ss.SSS) - 是否有可能? – user6492999

+0

@ user6492999 1)你**應該**鎖定它。當你**插入**一個新的交易時,你想確保你**選擇**最後一個的餘額。如果您期望高流量,請確保您閱讀數據庫事務以優化操作並避免死鎖。 – Edu

+0

@ user6492999 2)我認爲精度非常高,但即使我會測試兩個連續插入是否可能具有相同的日期時間,這可能會導致不一致。日期時間精度可以在數據庫引擎文檔中找到。對於Postgresql,您可以在這裏找到最新版本(9.6):https://www.postgresql.org/docs/9.6/static/datatype-datetime.html – Edu