作者:伊克巴尔汗
NCache 让您可以在中间层更靠近应用程序缓存数据,这样您就可以减少昂贵的数据库访问。 这反过来显着加快了您的应用程序。 它还使其更具可扩展性,因为减少了数据库上的负载,使其无需任何硬件升级即可处理大量客户端。
但是,当您缓存数据时,您实际上是在数据库之外创建它的副本。 这引入了数据库中的数据将被修改但缓存副本将保持不变并变得陈旧的风险。 好消息是,只有当您有多个应用程序修改数据库中的相同数据并且并非所有应用程序都在更新缓存时,才会出现这种情况。
当您遇到其他应用程序正在修改数据库中的数据而不更新缓存的情况时,您需要一种机制让缓存能够直接与数据库同步。 这可以通过多种不同的方式实现。 如果您的数据库是 SQL Server 2008/2012,那么缓存可以使用 .NET 事件通知进行同步,这非常有效。 但是,如果您的数据库是 SQL Server 2000、Oracle 或任何其他兼容 OLEDB 的数据库,那么同步的唯一方法是轮询数据库以查找任何更新。 这种方法当然效率不高,因为缓存最终会对数据库进行大量不必要的访问。
在这篇文章中,我将讨论如何 NCache 使用 .NET 事件通知将缓存与 SQL Server 2008/2012 数据库同步。
为了使用此功能,您需要在 .NET 应用程序代码中指定以下内容。 NCache 提供了一个非常类似于微软的界面 SqlCacheDependency
接口,因为在内部 NCache 正在使用 SqlCacheDependency
要与 SQL Server 2008/2012 同步的对象。
public class Program {
public static void Main(string[] args)
{
NCache.InitializeCache("myCache");
Customer cust = new Customer();
cust.CustomerID = "ALFKI";
LoadCustomer(cust);
List<Customer> custList = FindCustomers("San Francisco");
// Do your regular work here...
NCache.Cache.Dispose();
}
// A standard Load method that loads a single row from database
public Customer LoadCustomer(Customer cust)
{
String key = "Customer:CustomerID:" + cust.CustomerID;
Customer cust2 = (Customer)NCache.Cache.Get(key);
if (cust2 != null)
return cust2;
CustomerFactory custFactory = new CustomerFactory();
// Load a single customer from the database
// SELECT * FROM Customers WHERE CustomerID = 'ALFKI'
custFactory.Load(cust);
// Create a SqlCacheDependency for this item
CacheItem item = new CacheItem(cust);
item.Dependency = SqlDependencyFactory.CreateSqlYukonDependency(connectionString,
"SELECT CustomerID FROM Customers WHERE CustomerID = '" + cust.CustomerID + "'");
// Store item in the cache along with SqlCacheDependency
NCache.Cache.Insert(key, item);
return cust;
}
// A query method
public List<Customer> FindCustomers(String city)
{
String key = "List<Customer>:City:" + city;
List<Customer> custList = (List<Customer>)NCache.Cache.Get(key);
if (custList != null)
return custList;
CustomerFactory custFactory = new CustomerFactory();
// Load a list of customers from database based on a criteria
// SELECT * FROM Customers WHERE City = 'San Francisco'
custList = custFactory.FindByCity(city);
// Create a SqlCacheDependency for this list of customers
CacheItem item = new CacheItem(custList);
item.Dependency = SqlDependencyFactory.CreateSqlYukonDependency(connectionString,
"SELECT CustomerID FROM Customers WHERE City = '" + city + "'");
// Store list of customers in the cache along with SqlCacheDependency
NCache.Cache.Insert (key, item);
return custList;
}
}
上面的代码显示了两种不同的情况,您可以在其中指定 SqlCacheDependency
。首先是当您从数据库加载一行、将其转换为对象并将其存储在缓存中时。在这种情况下,请注意,您必须指定在代码中使用的等效 SQL 语句来获取这一单行。然后使用该 SQL 语句 SqlCacheDependency 对象建立与数据库的连接并注册 SQL Server 2008/2012 应为其发送 .NET 事件通知的行。
第二种情况是您从数据库中获取行集合作为对象集合,然后将整个集合作为单个对象存储在缓存中。 在这种情况下,您需要创建一个 SqlCacheDependency
它使用相同的 SQL 语句从数据库中获取您刚刚执行的相同行。 这边走, NCache 通知 SQL Server 2008/2012,当这些行中的任何一个发生更改时,应将 .NET 事件通知发送到 NCache.
上面的代码示例涵盖了大多数需要指定 SqlCacheDependency
在你的代码中。 另一种情况是当您尝试获取客户相关对象的集合时(例如 1-n 关系)。 在这种情况下,您将完全按照您为获取 Customer 对象的集合所做的操作。 唯一会改变的是用于获取相关对象的 SQL 语句。
请注意您提供给的 SQL 语句 CreateSqlYukonDependency()
方法不得使用 "SELECT * ..."
格式。 您必须指定一个或多个列名作为 SELECT
陈述。 除此以外, SqlCacheDependency
不会工作。
您必须先在 SQL Server 2008/2012 中启用服务代理 NCache 可以使用 SqlCacheDependency
. 这允许 SQL Server 2008/2012 将事件通知发送到 NCache 让它知道数据库中的数据已更改。
ALTER DATABASE Northwind SET ENABLE_BROKER;
GO
请注意: NCache 自动调用 SqlCacheDependency.Start()
方法从它自己的代码中。 您从不直接与 SqlCacheDependency
因此不需要调用 "Start()"
方法就可以了。
你现在已经准备好运行你的应用程序了 NCache 调用缓存数据。 现在,每当您将任何内容缓存在 NCache, NCache 通知 SQL Server 2008/2012,然后当此数据在 SQL Server 2008/2012 中发生更改时,它会发送一个 .NET 事件通知到 NCache. NCache 然后从缓存中删除此数据,因为它在数据库中已更改。 这样,下次你的应用程序需要这些数据时,它不会在缓存中找到它,而是去数据库获取它,然后存储在缓存中。
如您所见, NCache 使您的分布式缓存与 SQL Server 2008/2012 数据库同步变得非常简单。 现在,您可以放心,您的缓存永远不会与数据库不同步。
作者: 伊克巴尔·汗为 Alachisoft ,一家领先的软件公司,提供 .NET 和 Java 分布式缓存、O/R 映射和 SharePoint 存储优化解决方案。 你可以联系他 伊克巴尔@alachisoft .