`
soboer
  • 浏览: 1310067 次
文章分类
社区版块
存档分类
最新评论

DataRabbit 轻量的数据访问框架(20)-- 实时同步的实体缓存 SyncEntityCache

阅读更多

在系统架构设计中,使用缓存是最常用的降低数据库负载和提升性能的策略,缓存的主要目的是减少对数据库的Read操作。但是在不同的情况下,我们需要使用不同形式的缓存。

比如,如果数据表中的数据是静态的、不会发生变化的,那就非常容易,我们只需要在系统启动的时候,将其加载到内存,以后每次从内存读取数据即可。

再比如,数据表中的数据会发生变化(增删改),但是变化的频率非常低,而恰巧我们的系统对数据实时性的敏感度也不是特别高,那我们可以使用定时刷新的缓存,DataRabbit 中也内置了对这种缓存的支持,可以参见 DataRabbit 轻量的ORM框架(16)-- Entity缓存

再比如,数据表中的记录非常多,并且修改方面只会有Insert操作,那么我们可以使用HotCache,把那些经常使用的记录缓存在内存中,并且设定超时机制。HotCache我们会在后面介绍。

再比如,某个数据表的修改经常是Insert和Update操作,但是无论如何Update,每条记录有些固定栏位的值都是不会发生变化的,那我们可以把这些不会发生变化的栏位封装在一个【子对象】中,然后在内存中缓存这些子对象。

举了这么多例子,现在我们进入本文正题,假设我们的某个数据表中的数据会发生变化(增删改),但是变化的频率比较低,但是我们的系统对这个表的数据的实时性的敏感度也特别高,那这时候我们就需要用到【实时同步的实体缓存】,这个缓存中的数据在任何时候都与数据表中的数据是完全一致的。

DataRabbit 中的SyncEntityCache就是这样的缓存。

当然,使用这样的实时同步缓存有一个前提是必须保证的,那就是对目标数据表的修改都必须经由SyncEntityCache来进行,这个前提应该还是比较容易保证的。

我们来看看ISyncEntityCache接口的内容:

该接口有两个泛型参数:TPKey和TEntity,TPKey表示数据表主键的类型,TEntity就是目标Entity的类型。

其三个属性分别是:

TransactionScopeFactory 表明目标数据表位于哪个数据库中。

PKeyName 即主键列的名称。

PKeyAutoIncreased 表示主键是否为自增类型。

然而,能被缓存的Entity必须实现ISyncCachedEntity接口:

基接口ICachedEntity的GetID()方法用于返回Entity的主键字段的值。ISyncCachedEntity继承了ICloneable接口,表明Entity是必须可以复制的,继承这个接口的缘由后面会介绍到。

当系统启动时,我们调用Initialize方法从数据库中加载目标表的所有记录。接着我们就可以通过GetEntityCopy()方法和GetEntityCopyList()方法来读取需要的Entity。注意这两个方法的名称中包含了“Copy”,这表明它们会返回缓存的Entity的副本。所以,即使你对返回的副本进行修改,也不会影响到缓存中的Entity。

显然,这两种方法的效率会因为Entity的clone而有轻微降低。但是,如果你能保证读取的Entity仅用于Read,那么你可以调用GetEntityList4Read()这个效率更高的方法,它将直接返回缓存中的Entity。

另外,你看到ISyncEntityCache提供了基本的增删改的方法,我们必须调用这些方法来修改目标数据表中的记录,而且这些方法会自动同步缓存中的Entity使其与数据库中一致。

最后,ISyncEntityCache提供了Reload()方法,该方法用于目标数据表中的记录在意外的情况下发生修改时(即修改不是通过ISyncEntityCache进行的),手动刷新缓存以获得与数据库中的数据完全的一致性。

DataRabbit.Application.Cache.SyncEntityCache 类实现了ISyncEntityCache接口,并且这个实现是线程安全的,你可以在多线程的环境下放心使用。

DataRabbit3.0及以上版本对上述策略都给予了充分的支持,你可以下载最新版本试试。

关于DataRabbit的更多信息目录,参见这里

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics