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版]
- 增刪改查入門。快速展現用法,程式碼配置連線字串
- 資料模型檔案。建立表格欄位和索引,名字以及資料型別規範,推薦欄位(時間,使用者,IP)
- 物體類詳解。資料類業務類,泛型基類,介面
- 功能設定。連線字串,除錯開關,SQL日誌,慢日誌,引數化,執行超時。程式碼與配置檔案設定,連線字串區域性設定
- 反向工程。自動建立資料庫資料表
- 資料初始化。InitData寫入初始化資料
- 高階增刪改。多載攔截,自增欄位,Valid驗證,物體模型(時間,使用者,IP)
- 臟資料。如何產生,怎麼利用
- 增量累加。高併發統計
- 事務處理。單表和多表,不同連線,多種寫法
- 擴充套件屬性。多表關聯,Map對映
- 高階查詢。複雜條件,分頁,自定義擴充套件FieldItem,查總記錄數,查彙總統計
- 資料層快取。Sql快取,更新機制
- 物體快取。全表整理快取,更新機制
- 物件快取。字典快取,適用使用者等資料較多場景。
- 百億級效能。欄位精煉,索引完備,合理查詢,充分利用快取
- 物體工廠。元資料,通用處理程式
- 角色許可權。Membership
- 匯入匯出。Xml,Json,二進位制,網路或檔案
- 分表分庫。常見拆分邏輯
- 高階統計。聚合統計,分組統計
- 批次寫入。批次插入,批次Upsert,非同步儲存
- 物體佇列。寫入級快取,提升效能。
- 備份同步。備份資料,恢復資料,同步資料
- 資料服務。提供RPC介面服務,遠端執行查詢,例如SQLite網路版
- 大資料分析。ETL抽取,排程計算處理,結果持久化
受蘋果公司新規定影響,微信 iOS 版的贊賞功能被關閉,可透過二維碼轉賬支援公眾號。