2011-10-03 31 views
6

¿Hay alguna manera de notificar a un servidor web (en mi caso, un servidor web que aloja una aplicación web MVC2 en C#) que hubo un cambio en la base de datos? El objetivo es mantener el caché del servidor web sincronizado con la base de datos.Servidor SQL notifica al servidor web del cambio de tabla

Existen construcciones de sondeo en ASP.NET que permiten esto, pero prefiero un sistema de inserción. También estoy bajo la suposición de que la base de datos puede ser manipulada por elementos que no sean el servidor web en sí.

Mi conocimiento limitado de SQL Server/ASP MVC dice que una manera es mediante la creación de una tabla de GATILLO que casi golpea una url que forzará una actualización.

Respuesta

7

SqlDependency es el camino a seguir, si la tasa de cambio es moderada. Para obtener altas tasas de cambio, es mejor que realice una encuesta para conocer los cambios. Para comprender cómo funciona SqlDependency, lea The Mysterious Notification. ASP ya tiene soporte integrado para SqlDependency, es decir, el SqlCacheDependency. También hay LinqToCache que agrega capacidad de SqlDependency a cualquier consulta LINQ arbitraria, si es posible.

El disparador es absolutamente un gran no-no. No puede hacer que las transacciones de la base de datos esperen que alguna URL responda, su rendimiento se colapsará, básicamente, a nada. Sin mencionar el problema de la disponibilidad (las actualizaciones fallarán si la URL no responde, por el motivo que sea).

+0

parece que SqlCacheDependency (SqlCommand) es lo que estoy buscando, ya que hace el esfuerzo de asegurar entrega. Pero me perdiste por la sugerencia de que la votación sería preferible al método de notificación de consultas. ¿El costo de las encuestas es una vez más eficiente que la prueba requerida para ver si una inserción solicitada para la notificación se ha visto afectada por alguna inserción/actualización/eliminación? –

+1

El costo de entregar la notificación es significativo. Si configura una notificación únicamente para ser inmediatamente invalidada por la alta tasa de cambios, es mejor simplemente verificar el valor directamente. Es una línea fina en la que el punto en el que es mejor votar varía de una aplicación a otra, de una tabla a otra. Tendrá que medir y ver el impacto de uno frente al otro, bajo una carga pesada. –

1

Su "conocimiento limitado de SQL Server" es suficiente. Debería crear un desencadenador DESPUÉS DE INSERTAR, ACTUALIZAR, ELIMINAR que hará lo que necesita.

Otra cosa es que esto es una mala idea, pero es probable que estés consciente de ello ..

La forma correcta de resolver este tipo de problemas es utilizar algún tipo de cola de mensajes, por ejemplo. MsMQ.

2

La única forma en que puedo pensar es escribir una función CLR definida por el usuario (UDF) e invocarla mediante insertar/actualizar/eliminar activadores en la (s) tabla (s) de interés.

La UDF debe engendrar un hilo que avisa al servidor web e inmediatamente vuelve al activador. Por razones obvias, se considera una forma realmente mala invocar dentro de un desencadenante o una transacción en ejecución cualquier operación potencialmente larga o que falle (como acceder a la red). A menos que, por supuesto, disfrute de la ira de los DBA de producción que bajan te gusta el martillo de plata de Maxwell.

4

No tengo la experiencia, pero la clase System.Data.SqlClient.SqlDependency parece que necesita.

De acuerdo con MSDN:

SqlDependency es ideal para escenarios de almacenamiento en caché, donde su aplicación ASP.NET o servicio de nivel medio tiene que mantener cierta información en caché en la memoria. SqlDependency le permite recibir notificaciones cuando los datos originales en la base de datos cambian para que la memoria caché pueda actualizarse.

0

Para recibir notificaciones de la base de datos cuando se cambia/actualiza el contenido de la tabla, puede usar TableDependency.

La diferencia con .NET SqlDependency es que TableDependency levanta eventos que contienen los valores de tabla de base de datos modificados/eliminados/insertados.

Usando SqlDependency tiene que ejecutar una selección para obtener datos nuevos en cualquier momento SqlDependency notifique a su código que algo ha cambiado en la tabla de la base de datos.

Con TableDependency puede evitarlo porque el evento que recibe contiene todos los valores borrados/insertadas/modificados:

string conString = "data source=.;initial catalog=myDB;integrated security=True"; 

using(var tableDependency = new SqlTableDependency<Customers>(conString)) 
{ 
    tableDependency.OnChanged += TableDependency_Changed; 
    tableDependency.Start(); 

    Console.WriteLine("Waiting for receiving notifications..."); 
    Console.WriteLine("Press a key to stop"); 
    Console.ReadKey(); 
} 
... 
... 
void TableDependency_Changed(object sender, RecordChangedEventArgs<Customers> e) 
{ 
    if (e.ChangeType != ChangeType.None) 
    { 
     var changedEntity = e.Entity; 
     Console.WriteLine("DML operation: " + e.ChangeType); 
     Console.WriteLine("ID: " + changedEntity.Id); 
     Console.WriteLine("Name: " + changedEntity.Name); 
     Console.WriteLine("Surname: " + changedEntity.Surname); 
    } 
}