Sincronice la caché de objetos distribuidos con SQL Server 2008/2012

Autor: Iqbal Kan

NCache le permite almacenar datos en caché más cerca de su aplicación en el nivel medio para que pueda reducir los costosos viajes a la base de datos. Esto, a su vez, acelera significativamente su aplicación. También lo hace más escalable porque la carga en su base de datos se reduce, lo que le permite manejar una mayor cantidad de clientes sin actualizaciones de hardware.

Sin embargo, cuando almacena datos en caché, en realidad está creando una copia fuera de su base de datos. Esto presenta el riesgo de que los datos en su base de datos se modifiquen pero su copia en caché permanezca sin cambios y se vuelva obsoleta. La buena noticia es que esta situación ocurre solo cuando tiene múltiples aplicaciones modificando los mismos datos en la base de datos y cuando no todas están actualizando el caché.

Cuando se encuentra en una situación en la que otras aplicaciones modifican datos en la base de datos y no actualizan la memoria caché, entonces necesita un mecanismo para que la memoria caché pueda sincronizarse directamente con la base de datos. Esto es posible de múltiples maneras diferentes. Si su base de datos es SQL Server 2008/2012, la memoria caché puede usar notificaciones de eventos .NET para la sincronización, lo cual es bastante eficiente. Pero, si su base de datos es SQL Server 2000, Oracle o cualquier otra base de datos compatible con OLEDB, entonces la única forma de sincronizar es sondeando la base de datos en busca de actualizaciones. Por supuesto, este método no es tan eficiente porque el caché termina haciendo muchos viajes innecesarios a la base de datos.

En este artículo, discutiré cómo NCache sincroniza la memoria caché con la base de datos de SQL Server 2008/2012 mediante el uso de notificaciones de eventos de .NET.

Especificación SqlCacheDependency en codigo

Esto es lo que necesita especificar en el código de su aplicación .NET para poder utilizar esta función. NCache proporciona una interfaz muy similar a la de Microsoft SqlCacheDependency interfaz porque internamente NCache esta usando SqlCacheDependency objeto para sincronizar con 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;
    }
}

El código anterior muestra dos situaciones diferentes en las que puede especificar SqlCacheDependency. La primera es cuando cargas una sola fila de la base de datos, la conviertes en un objeto y la almacenas en la caché. En este caso, tenga en cuenta que debe especificar una declaración SQL equivalente a la que utilizó en su código para recuperar esta única fila. Esta declaración SQL luego es utilizada por SqlCacheDependency objeto para establecer una conexión con la base de datos y registrar las filas para las que SQL Server 2008/2012 debe enviar notificaciones de eventos .NET.

La segunda situación es cuando obtiene una colección de filas de la base de datos como una colección de objetos y luego almacena la colección completa como un objeto individual en el caché. En este caso, debe crear un SqlCacheDependency que usa la misma instrucción SQL para obtener las mismas filas que acaba de hacer de la base de datos. De esta manera, NCache notifica a SQL Server 2008/2012 que cuando alguna de estas filas cambie, se debe enviar una notificación de evento de .NET a NCache.

El ejemplo de código anterior cubre la mayoría de las situaciones en las que necesitaría especificar un SqlCacheDependency en tu código. Otra situación es cuando intenta obtener una colección de objetos relacionados con el Cliente (por ejemplo, relación 1-n). En esa situación, hará exactamente lo que hizo para obtener una colección de objetos Cliente. Lo único que cambiaría es la instrucción SQL que se utiliza para obtener objetos relacionados.

Tenga en cuenta que la declaración SQL que le da a CreateSqlYukonDependency() método no debe utilizar "SELECT * ..." formato. Debe especificar uno o más nombres de columna como parte del SELECT declaración. De lo contrario, SqlCacheDependency no funcionará

Habilitar Service Broker en SQL Server 2008/2012

Debe habilitar Service Broker en SQL Server 2008/2012 antes NCache puede utilizar SqlCacheDependency. Esto permite que SQL Server 2008/2012 envíe notificaciones de eventos a NCache para hacerle saber que los datos han cambiado en la base de datos.

ALTER DATABASE Northwind SET ENABLE_BROKER;
GO

Ten en cuenta que NCache llama automáticamente SqlCacheDependency.Start() método desde dentro de su propio código. Nunca interactúas directamente con SqlCacheDependency y por lo tanto no necesita llamar "Start()" método en él.

Ejecutar aplicación

Ahora está listo para ejecutar su aplicación que hace NCache llamadas a la caché de datos. Ahora, siempre que almacene en caché algo en NCache, NCache notifica a SQL Server 2008/2012 al respecto y luego, cuando estos datos cambian en SQL Server 2008/2012, envía una notificación de evento .NET a NCache. NCache luego elimina estos datos del caché porque han cambiado en la base de datos. De esta manera, la próxima vez que su aplicación necesite estos datos, no los encontrará en el caché y irá a la base de datos para buscarlos y luego los almacenará en el caché.

Conclusión

Como has visto, NCache hace que sea muy sencillo sincronizar su caché distribuida con su base de datos de SQL Server 2008/2012. Ahora, puede tener la tranquilidad de saber que su caché nunca pierde la sincronización con su base de datos.


Escrito por: Iqbal Khan trabaja para Alachisoft , una empresa de software líder que ofrece soluciones de almacenamiento en caché distribuido .NET y Java, mapeo O/R y optimización de almacenamiento de SharePoint. Puedes localizarlo en iqbal@alachisoft.com.

© Copyright Alachisoft 2002 - Todos los derechos reservados. NCache es una marca registrada de Diyatech Corp.