在系統(tǒng)架構(gòu)設(shè)計(jì)中,使用緩存是最常用的降低數(shù)據(jù)庫(kù)負(fù)載和提升性能的策略,緩存的主要目的是減少對(duì)數(shù)據(jù)庫(kù)的 Read 操作。但是在不同的情況下,我們需要使用不同形式的緩存。
比如,如果數(shù)據(jù)表中的數(shù)據(jù)是靜態(tài)的、不會(huì)發(fā)生變化的,那就非常容易,我們只需要在系統(tǒng)啟動(dòng)的時(shí)候,將其加載到內(nèi)存,以后每次從內(nèi)存讀取數(shù)據(jù)即可。
再比如,數(shù)據(jù)表中的數(shù)據(jù)會(huì)發(fā)生變化(增刪改),但是變化的頻率非常低,而恰巧我們的系統(tǒng)對(duì)數(shù)據(jù)實(shí)時(shí)性的敏感度也不是特別高,那我們可以使用定時(shí)刷新的緩存,DataRabbit 中也內(nèi)置了對(duì)這種緩存的支持,可以參見 DataRabbit 輕量的ORM框架(16)-- Entity緩存 。
再比如,數(shù)據(jù)表中的記錄非常多,并且修改方面只會(huì)有Insert操作,那么我們可以使用HotCache,把那些經(jīng)常使用的記錄緩存在內(nèi)存中,并且設(shè)定超時(shí)機(jī)制。HotCache我們會(huì)在后面介紹。
再比如,某個(gè)數(shù)據(jù)表的修改經(jīng)常是Insert和Update操作,但是無論如何Update,每條記錄有些固定欄位的值都是不會(huì)發(fā)生變化的,那我們可以把這些不會(huì)發(fā)生變化的欄位封裝在一個(gè)【子對(duì)象】中,然后在內(nèi)存中緩存這些子對(duì)象。
舉了這么多例子,現(xiàn)在我們進(jìn)入本文正題,假設(shè)我們的某個(gè)數(shù)據(jù)表中的數(shù)據(jù)會(huì)發(fā)生變化(增刪改),但是變化的頻率比較低,但是我們的系統(tǒng)對(duì)這個(gè)表的數(shù)據(jù)的實(shí)時(shí)性的敏感度也特別高,那這時(shí)候我們就需要用到【實(shí)時(shí)同步的實(shí)體緩存】,這個(gè)緩存中的數(shù)據(jù)在任何時(shí)候都與數(shù)據(jù)表中的數(shù)據(jù)是完全一致的。
DataRabbit 中的SyncEntityCache就是這樣的緩存。
當(dāng)然,使用這樣的實(shí)時(shí)同步緩存有一個(gè)前提是必須保證的,那就是對(duì)目標(biāo)數(shù)據(jù)表的修改都必須經(jīng)由SyncEntityCache來進(jìn)行,這個(gè)前提應(yīng)該還是比較容易保證的。
我們來看看ISyncEntityCache接口的內(nèi)容:
該接口有兩個(gè)泛型參數(shù):TPKey和TEntity,TPKey表示數(shù)據(jù)表主鍵的類型,TEntity就是目標(biāo)Entity的類型。
其三個(gè)屬性分別是:
TransactionScopeFactory 表明目標(biāo)數(shù)據(jù)表位于哪個(gè)數(shù)據(jù)庫(kù)中。
PKeyName 即主鍵列的名稱。
PKeyAutoIncreased 表示主鍵是否為自增類型。
然而,能被緩存的Entity必須實(shí)現(xiàn)ISyncCachedEntity接口:
基接口ICachedEntity的GetID()方法用于返回Entity的主鍵字段的值。ISyncCachedEntity繼承了ICloneable接口,表明Entity是必須可以復(fù)制的,繼承這個(gè)接口的緣由后面會(huì)介紹到。
當(dāng)系統(tǒng)啟動(dòng)時(shí),我們調(diào)用Initialize方法從數(shù)據(jù)庫(kù)中加載目標(biāo)表的所有記錄。接著我們就可以通過GetEntityCopy()方法和GetEntityCopyList()方法來讀取需要的Entity。注意這兩個(gè)方法的名稱中包含了“Copy”,這表明它們會(huì)返回緩存的Entity的副本。所以,即使你對(duì)返回的副本進(jìn)行修改,也不會(huì)影響到緩存中的Entity。
顯然,這兩種方法的效率會(huì)因?yàn)镋ntity的clone而有輕微降低。但是,如果你 能保證 讀取的Entity僅用于Read,那么你可以調(diào)用GetEntityList4Read()這個(gè)效率更高的方法,它將直接返回緩存中的Entity。
另外,你看到ISyncEntityCache提供了基本的增刪改的方法,我們必須調(diào)用這些方法來修改目標(biāo)數(shù)據(jù)表中的記錄,而且這些方法會(huì)自動(dòng)同步緩存中的Entity使其與數(shù)據(jù)庫(kù)中一致。
最后,ISyncEntityCache提供了Reload()方法,該方法用于目標(biāo)數(shù)據(jù)表中的記錄在意外的情況下發(fā)生修改時(shí)(即修改不是通過ISyncEntityCache進(jìn)行的),手動(dòng)刷新緩存以獲得與數(shù)據(jù)庫(kù)中的數(shù)據(jù)完全的一致性。
DataRabbit.Application.Cache.SyncEntityCache 類實(shí)現(xiàn)了ISyncEntityCache接口,并且這個(gè)實(shí)現(xiàn)是線程安全的,你可以在多線程的環(huán)境下放心使用。
DataRabbit3.0及以上版本對(duì)上述策略都給予了充分的支持,你可以下載 最新版本 試試。
關(guān)于DataRabbit的更多信息目錄,參見 這里 。
DataRabbit 輕量的數(shù)據(jù)訪問框架(20)-- 實(shí)時(shí)同步的實(shí)體緩存 SyncEntityCache
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
