通过轮询将分布式缓存与数据库同步

介绍

NCache 是一种分布式缓存解决方案,可帮助加速您的应用程序,同时减少昂贵的数据库访问。 这反过来又增加了可扩展性,因为大量客户端从数据库移动到缓存,从而减少了数据库的负载并消除了升级硬件的需要。

当数据被添加到缓存中时,您实际上将数据库中原始数据的副本放入缓存中。 当数据库中的特定数据被更新时,它在缓存中的副本不受影响,因此变得陈旧。 但是,这种情况只有在有多个应用程序更新数据库中的相同数据但并非所有应用程序都负责更新缓存中的数据时才会出现。

在这种情况下,当某些应用程序正在更新数据库中的数据但不更新缓存时,您需要一种将缓存与数据库同步的方法,以便对数据库中数据的任何修改也会影响缓存中的数据。 这可以通过启用事件通知或轮询数据库以查找更新来实现。 但是,如果您的应用程序使用的数据库之一是 SQL Server 2000、旧版本的 Oracle 或其他不支持事件通知的 OLEDB 兼容数据库,则与之同步的唯一方法是使用轮询。

在本文中,我们将进一步研究如何 NCache 使用轮询将缓存与数据库同步。

在代码中使用 DbDependency

这是您需要在应用程序中实现的示例代码,以便通过轮询将数据库与缓存同步。

String conString = "Provider=OraOLEDB.Oracle;User Id=SYSTEM;" +
"Password=xe;Data Source=xe;OLEDB.NET=true;";

OleDbConnection con = new OleDbConnection(conString);
con.Open();

String sqlCmd = "SELECT ProductID, ProductName FROM dbo.Products WHERE ProductID < 12";

OleDbCommand cmd = new OleDbCommand(sqlCmd,con);
cmd.ExecuteReader();

OleDbDataReader myReader = cmd.ExecuteReader();

List<Products> lstProducts = new List<Products>();
while (myReader.Read())
    {
        Products cProducts = new Products();
        cProducts.ProductID = myReader.GetInt32(0);
        cProducts.ProductName = myReader.GetString(1);
        cProducts.SupplierID = myReader.GetInt32(2);
        cProducts.UnitPrice = myReader.GetDecimal(4);

        CacheItem item = new CacheItem(cProducts);

        DBCacheDependency dependency =
        DBDependencyFactory.CreateOleDbCacheDependency(conString,"");

        _cache.Insert(cProducts.ProductID + ":dbo.Products", cProducts,
        dependency, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration,
        CacheItemPriority.Default);

        lstProducts.Add(cProducts);
    };
myReader.Close();
con.Close();

在上面的代码中,加载了数据库中的一行并将其转换为一个对象。 之后,使用 CreateOleDbCacheDependency 建立与数据库的连接,并为其注册行 NCache 应该寻找更新。 请注意,当您使用 CreateOleDbCacheDependency 创建 OleDB 依赖项时,您必须为其提供与之前在代码中用于获取特定行的相同 SQL 语句。

上述代码实现并执行后, NCache 将在每个指定的清理间隔后继续访问数据库并获取任何更新的行,然后用缓存中相应的过期行替换它们。

配置数据库

我们已经在上面的代码中看到了如何 NCache 实现与数据库的同步。 但是,启用基于轮询的同步的过程需要更多步骤,我们将在下面看到。

  1. 创建一个表'ncache_db_sync' 并添加四个字段:(1) cache_key VARCHAR2,(2) cache_id VARCHAR2,(3) modified NUMBER 和 (4) work_in_progress NUMBER。
  2. 下面是创建表的 SQL:

    Create table ncache_db_sync
        (
            cache_key varchar2(256) not null enable,
            cache_id varchar2(256) not null enable,
            modified number(2,1) default 0 not null enable,
            work_in_progress number(2,1) default 0 not null enable,
            primary key (cache_key, cache_id) enable
        );
  3. 为需要通知的每个表创建 UPDATE 和 DELETE 触发器。 触发器将用于设置相应行的“修改”字段 ncache_db_sync 表为 1。
  4. /*Here is the SQL to create the trigger:*/
    Create Trigger MyTrigger
    After
    Update [or delete] on dbo.Products
    Referencing OLD AS oldRow
    For each row
     
     Begin
     Update ncache_db_sync
     Set modified = 1
     Where cache_key = (Cast(Select oldRow.ProductID FROM deleted OLD) As VarChar)
    + ':dbo.Products'
    End Trigger;

请注意: cache_key 必须与用于在缓存中添加相应记录的键相同。

触发器和'的方式ncache_db_sync' 表的工作原理是,每当数据库表中的值被更改或删除时,都会自动调用相应的触发器。 触发器将更改 ' 的 'modified' 字段的值ncache_db_sync'表为1,表示主键的值已被修改。

NCache 在每个指定时间段后执行缓存中过期和不必要的项目的清理。 这段时间称为清洁间隔。 在每个干净的间隔, NCache 还会在 ' 中查找 'modified' 字段的值ncache_db_sync 表。 如果发现该值为“1”,则 NCache 然后从缓存中删除适当的过期键,并从数据库中获取所有更新的行并放入缓存中。

笔记:

  1. 这是一个基于行的依赖。 缓存键与表的主键值相关联。 这意味着仅当具有该主键的行发生更改时,项目才会过期。
  2. cache_key 值必须与用于在缓存中添加相应记录的值相同。

接下来做什么?

联系我们

联系电话
©版权所有 Alachisoft 2002 - 版权所有。 NCache 是 Diyatech Corp. 的注册商标。