歡迎光臨
每天分享高質量文章

[NewLife.XCode]增量累加

NewLife.XCode是一個有10多年曆史的開源資料中間件,支持nfx/netstandard,由新生命團隊(2002~2019)開發完成並維護至今,以下簡稱XCode。

整個系列教程會大量結合示例代碼和運行日誌來進行深入分析,蘊含多年開發經驗於其中,代表作有百億級大資料實時計算專案。

開源地址:https://github.com/NewLifeX/X (求star, 729+)

回到目錄

累加的需求背景

一個網站,部署了兩台應用服務器,共用資料庫,其中文章表有個訪問次數的欄位。

現在需要記錄訪問次數,需要怎麼做?

var entity = Article.FindByID(9527);
entity.Views++;
entity.Update();

如果兩台服務器都有用戶訪問了9527這篇文章,訪問前Views是1000,訪問後是多少?1002?大部分情況下是1002,少數情況下可能是1001。

如果每台服務器都有100個用戶同時訪問這篇文章呢?那可就精彩了,最後訪問數可能是1001到1200之間的某個數。

按照教科書做法,我們似乎應該開個事務加個鎖,確保同時只能有一個用戶(執行緒)修改這一行資料。

且不說加鎖和事務成本有多高,光是為了一個欄位就鎖住這一行導致用戶無法更新這一行其它欄位,就讓人覺得挺不地道的。再者,訪問次數對於其它欄位來說,也許並沒有那麼重要。

聰明如你,可以想到這麼一個辦法:

update article set views=views+1 where id=9527

哈,這就是XCode增量累加的出發點,每個用戶(執行緒)執行自己的那一次,不管排隊先後,最終結果都將會是1200。

回到目錄

設置增量累加

在物體類靜態建構式中,可以設置需要增量累加的欄位

向 Meta.Factory.AdditionalFields 添加需要採用增量累加的欄位,執行update時才生成 x=x+123 樣子的陳述句。

測試代碼:

Update VisitStat Set Times=Times+123,Users=Users+1,IPs=IPs+1,UpdateTime='2019-03-26 22:36:14' Where ID=1

從輸出效果看到,產生了累加效果。並且,這段代碼不管執行多少次,都是這樣的累加效果,而不管實際值是多少。

回到目錄

累加原理

從資料庫查出來一個物件時,如果發現有設置累加欄位,XCode會把此時的資料“備份” 下來

在執行update儲存的時候,拿累加欄位的最後值減去原始備份值,得到差值(可能是負數),生成 x=x+123 或 x=x-456 的陳述句。

不光整數,小數也可以設置累加欄位。

需要註意的是,如果欄位x允許空,並且要更新行的x欄位剛好為NULL,x=x+123 將會得不到預期效果。

回到目錄

高級用法

再看開頭的例子,即使使用了累加,不需要加鎖以及開事務,仍然需要update資料庫200次。

借助累加以及異步儲存功能,可以把這個次數大大降低。

var entity = Article.FindByID(9527);
entity.Views++;
entity.SaveAsync(5_000);

先把Views設為累加欄位。

Article.FindByID內部可以用物件快取,然後每台應用服務器在10秒(預設快取時間)內多執行緒查到的都是同一個entity物件。

SaveAsync將把物件entity放入物體佇列,5秒後延遲儲存。如果200用戶訪問集中在5秒內,最後每台服務器只會執行一次update操作。

Update Article Set Viewss=Views+100 Where ID=9527

資料庫寫入次數由200次下降到2次,提升100倍。

由此,你能想到什麼更有意思的用法了嗎?

回到目錄

系列教程

NewLife.XCode教程系列[2019版]

  1. 增刪改查入門。快速展現用法,代碼配置連接字串
  2. 資料模型檔案。建立表格欄位和索引,名字以及資料型別規範,推薦欄位(時間,用戶,IP)
  3. 物體類詳解。資料類業務類,泛型基類,接口
  4. 功能設置。連接字串,除錯開關,SQL日誌,慢日誌,引數化,執行超時。代碼與配置檔案設置,連接字串區域性設置
  5. 反向工程。自動建立資料庫資料表
  6. 資料初始化。InitData寫入初始化資料
  7. 高級增刪改。多載攔截,自增欄位,Valid驗證,物體模型(時間,用戶,IP)
  8. 臟資料。如何產生,怎麼利用
  9. 增量累加。高併發統計
  10. 事務處理。單表和多表,不同連接,多種寫法
  11. 擴展屬性。多表關聯,Map映射
  12. 高級查詢。複雜條件,分頁,自定義擴展FieldItem,查總記錄數,查彙總統計
  13. 資料層快取。Sql快取,更新機制
  14. 物體快取。全表整理快取,更新機制
  15. 物件快取。字典快取,適用用戶等資料較多場景。
  16. 百億級性能。欄位精煉,索引完備,合理查詢,充分利用快取
  17. 物體工廠。元資料,通用處理程式
  18. 角色權限。Membership
  19. 匯入匯出。Xml,Json,二進制,網絡或檔案
  20. 分表分庫。常見拆分邏輯
  21. 高級統計。聚合統計,分組統計
  22. 批量寫入。批量插入,批量Upsert,異步儲存
  23. 物體佇列。寫入級快取,提升性能。
  24. 備份同步。備份資料,恢復資料,同步資料
  25. 資料服務。提供RPC接口服務,遠程執行查詢,例如SQLite網絡版
  26. 大資料分析。ETL抽取,調度計算處理,結果持久化

 

受蘋果公司新規定影響,微信 iOS 版的贊賞功能被關閉,可通過二維碼轉賬支持公眾號。

    赞(0)

    分享創造快樂