2009-01-08 8 views
7

Quiero escribir un servicio (probablemente en C#) que supervisa una tabla de base de datos. Cuando se inserta un registro en la tabla, quiero que el servicio tome los datos recién insertados y realice alguna lógica comercial compleja con él (demasiado complejo para TSQL).¿Pueden los activadores de SQL CLR hacer esto? ¿O hay un mejor camino?

Una opción es hacer que el servicio revise periódicamente la tabla para ver si se han insertado nuevos registros. El problema de hacerlo de esa manera es que quiero que el servicio sepa sobre los insertos tan pronto como suceden, y no quiero matar el rendimiento de la base de datos.

Haciendo un poco de investigación, parece que escribir un disparador CLR podría hacer el trabajo. Podría escribir desencadenador en C# que se dispara cuando se produce una inserción, y luego enviar los datos recién insertados a un servicio de Windows o WCF.

¿Qué crees que es un buen (o incluso posible) uso de los activadores SQL CLR?

¿Alguna otra idea sobre cómo lograr esto?

Respuesta

6

Probablemente se debe desacoplar de postprocesado de la inserción:

En el desencadenador de inserción, añadir PK del registro en una tabla de cola.

En un servicio separado, lea de la tabla de cola y realice su compleja operación. Cuando haya terminado, marque el registro como procesado (junto con la información de error/estado), o elimine el registro de la cola.

+0

Exactamente lo que iba a sugerir. Será transaccionalmente seguro y conservará los registros procesados ​​y no procesados ​​en una tabla que no afectará las tablas de aplicaciones principales. +1 para esta solución! – evilhomer

+2

Utilice el Servidor de servicios de SQL Server –

+0

Buena idea, excepto que pierde todo el rastro de las cosas que cambiaron (es decir, el contenido de la tabla ELIMINADO, disponible solo durante la ejecución del desencadenante). Depende de lo que necesites, supongo. –

3

Lo que está describiendo a veces se denomina cola de trabajos o cola de mensajes. Hay varios temas sobre el uso de una tabla DBMS (así como otras técnicas) para hacer esto que puede encontrar buscando.

Consideraría hacer algo así con un Trigger como un uso inapropiado de una función de base de datos que es fácil meterse en problemas de todos modos. Los desencadenantes se utilizan mejor para la funcionalidad estructural dbms de bajo costo (por ejemplo, comprobación de integridad referencial de grano fino) y deben ser livianos y sincrónicos. Podría hacerse, pero probablemente no sería una buena idea.

1

Tengo un servicio que sondea la base de datos cada minuto, no causa tantos problemas de rendimiento y es una solución limpia. Además, si su servicio u otro punto final wcf no está allí, su activador fallará o se perderá y tendrá que sondear de todos modos más adelante.

1

No recomendaría usar un disparador CLR ni ningún tipo de disparador para esto. Te estás abriendo a tener serios problemas de mantenimiento y posibles problemas de bloqueo. (Un activador muy simple que arroja cosas en una tabla de auditoría/cola puede ser aceptable SI no te importa @@ identity después de las inserciones y nunca bloquearás la tabla de auditoría/cola)

En cambio, desde tu aplicación/orm debe desencadenar la inserción de cosas en una tabla de cola y hacer que esta cola se procese de forma regular. Esto se puede hacer teniendo una transacción en su ORM o iniciando un proceso almacenado; el inicio de una transacción compromete el cambio y la auditoría/cola de forma atómica. (Cuidado con bloqueo aquí)

Si necesita una acción inmediata, busque en el desove un trabajo para borrar la cola después de hacer un insert/update/delete en la mesa y

también asegurarse de que son de doble comprobación de la haga cola una vez por minuto en caso de que el proceso en segundo plano no se haya iniciado correctamente. Si es una aplicación web y desea evitar los hilos de desove, podría comunicarse con un proceso en segundo plano para aclarar la cola.

-1

¿Por qué no implementar la inserción en un procedimiento almacenado, y hacer la lógica de negocios en el procedimiento después de la inserción? ¿Qué tiene de complicado que no se pueda escribir en T-SQL?

2

Sugeriría tener un disparador en la tabla que llame al SQL Server Service Broker, que luego (asincrónicamente) ejecuta un procedimiento CLR almacenado que hace todo tu trabajo en un hilo diferente.

+0

De acuerdo. El código .net ni siquiera tiene que ser un proceso almacenado clr; puede consumir los contenidos de la cola de otro proceso. –

Cuestiones relacionadas