2013-03-12 22 views
5

Stiamo eseguendo NServiceBus per un'applicazione Web per gestire le situazioni in cui l'utente esegue azioni "batch like". Come sparare un comando che colpisce 1000 entità ..I deadlock durante l'esecuzione del servizio NServicebus causano una connessione corrotta

Funziona bene, ma durante il carico moderato otteniamo alcuni deadlock, questo non è un problema, basta riprovare il messaggio .. giusto? :)

Il problema si verifica quando arriva il messaggio successivo e tenta di aprire una connessione. La connessione è quindi "corrotta".

otteniamo il seguente errore: System.Data.SqlClient.SqlException (0x80131904): Nuova richiesta non è consentito avviare perché dovrebbe venire con descrittore di transazione valido

Ho cercato nel web e penso il nostro problema è segnalato NH "bug":

Una soluzione alternativa dovrebbe essere quella di disabilitare il pool di connessioni. Ma non mi piace, dal momento che la performance peggiorerà ..

Stiamo eseguendo NServiceBus 2.6, NHibernate 3.3.

Qualcuno ha qualche esperienza con questo? Può un aggiornamento di NServiceBus aiutare?

+0

Sembra molto simile a un problema che stiamo riscontrando. Non l'abbiamo ancora risolto, e al momento stiamo zoppicando insieme al raggruppamento. Qual è la tua configurazione riguardo MSDTC? –

+0

Abbiamo 2 caselle Web (carico hardware bilanciato, ip-sticky) e un cluster di server SQL di failover con MS DTC Server. –

+0

Ora abbiamo disattivato il pool di connessioni e il problema non si verifica più. –

risposta

1

Ho visto questo in passato, se il progetto richiede, provare a rompere la transazione in due, se si scorre la transazione del messaggio fino alle operazioni del database, eventuali errori avranno un effetto a catena e avranno un impatto (idealmente non dovrebbe) qualsiasi messaggio successivo.

+0

Per aggiungere un po 'più di chiarezza, intendevo utilizzare una transazione nidificata. La transazione del database non dovrebbe avere un effetto sulla transazione complessiva del messaggio. –

+0

Rompiamo tutto in piccole transazioni brevi usando una saga. Ma quando si verifica ancora un deadlock, viene visualizzato l'errore quando il pool di connessioni è attivo. –

0

Invece di aggiornare le 1000 entità nel comando è possibile pubblicare un evento per dire che il comando è stato completato e quindi avere più sottoscrittori che agiscono su questo evento per aggiornare le entità dell'effetto. Mi sembra che un comando che aggiorna una 1000 entità debba essere diviso in un numero di comandi più piccoli. Dai un'occhiata alle saghe per scoprire come gestire un processo aziendale a lungo termine. Ad esempio, potresti avere qualcosa di simile, processo avviato, passaggio 1 completato, passaggio 2 completato, processo completato ecc ...

+0

Questo è quello che facciamo. Quando ad es. l'utente emette un comando che ha effetto su 1000 entità divise il comando in una per "entità". Ed è gestito da una saga. –

+0

Ma quando una delle transazioni viene bloccata in deadlock, la connessione restituita al pool di connessioni è corrotta e quando il servizio riprova il messaggio ottiene la connessione corrotta e viene visualizzato il messaggio di errore della transazione per tutti i nuovi messaggi. –