Domanda

Ho un'applicazione ASP.NET in esecuzione su più server Web IIS6, con un back-end di database SQL Server 2005.

Ho bisogno di:

  1. monitorare il database per il completamento di un evento di lavoro esterno, quindi

  2. fare in modo che esattamente un'istanza dell'applicazione Web invii alcune informazioni a un servizio Web

Per (1) sembra che una SqlDependency sarebbe l'approccio migliore (o semplicemente il vecchio polling).Ogni istanza dell'applicazione Web registrerebbe tale dipendenza all'avvio.(Non voglio configurare un'istanza "master" perché il fallimento di tale istanza significherebbe che l'attività non procede, anche se sono disponibili altre istanze.Pertanto il mio progetto è quello di garantire che se c'è un'istanza disponibile per svolgere il lavoro, allora il lavoro dovrebbe procedere).

Per (2) ho pensato di avere una sorta di flag nel database che le istanze dell'applicazione web tentano di aggiornare una volta ricevuta la notifica SqlDependency in (1), lungo la seguente riga (molto semplificata):

UPDATE StatusTable SET TaskStatus = 1 WHERE TaskStatus = 0

SELECT @@ROWCOUNT

L'idea è che solo un'istanza dell'applicazione sarebbe stata in grado di aggiornare TaskStatus e quindi solo un'istanza avrebbe un @@ROWCOUNT > 0.Questa sarebbe quindi l'istanza "eletta" per inviare le informazioni al servizio web.

Quali sono le carenze di questo approccio?Quali sono le mie altre opzioni?(Nota:un servizio separato che svolge questo lavoro non è un'opzione.)

È stato utile?

Soluzione

Una "bandiera" globale non funzionerà, tieni presente che hai più camerieri E più notifiche, non vuoi che un "cameriere" venga a ritirare Tutto notifiche.Per selezionare in modo affidabile "esattamente una" attività, utilizzare UPDATE con OUTPUT:

UPDATE TOP(1) StatusTable
   SET Status = 1
OUTPUT DELETED.TaskId
WHERE Status = 0;

Questo è il modo consigliato e affidabile per rimuovere dalla coda le righe dalle tabelle utilizzate come code, vedere il paragrafo Code in Clausola di USCITA.

Ma a questo punto dovresti capire che 1) stai utilizzando tabelle come code 2) stai ricevendo notifiche da queste code e 3) utilizzi Service Broker per inviare queste notifiche (tramite SqlDependency, che utilizza internamente Service Broker).Allora perché non utilizzare semplicemente Service Broker?Avete bisogno di un coda e un servizio e fare in modo che ogni istanza inizi a ATTESA(RICEVI...) su questa coda (che è non sondaggio).Il lavoro di interesse termina il suo lavoro con a INVIARE al tuo servizio, notificando che un lavoro è stato completato.Esattamente una delle tue istanze raccoglierà questa notifica e porterà avanti la post-elaborazione (ad es.erogare la chiamata al servizio web).In questo modo elimini tutta la "lanugine" attorno alle notifiche (SqlDependency, flag globale, tabelle utilizzate come code) e vai contro l'infrastruttura semplice che verrebbe comunque utilizzata da SqlDependency.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top