Sto cercando di consumare una coda Kafka ad un alto tasso di elaborazione e memorizzare il risultato in MySql usando EF da .net core 2.1 Ho provato ad usare sia AddDbContext
che AddDbContextPool
e ho eseguito entrambi gli scenari in problemi.
1) Quando si utilizza AddDbContext
l'unico modo in cui ero riuscito era quello di renderlo transient
modo da ottenere una nuova istanza DataContext
ogni volta che ho bisogno di chiamare l'inserto dati. La mia coda è grande e finisco per avere troppe connessioni al server mqSQL quindi alla fine comincio a ricevere tonnellate di errori di timeout.
So che posso aggiungere opzioni per riprovare gli errori transitori (e il timeout è uno di questi), ma sono principalmente interessato a come ridurre il numero di istanze di DataContext
al numero che non martellerebbe il database. Questo mi ha portato al prossimo tentativo
2) Quando si utilizza AddDbContextPool
non ero in grado di impostare l'ambito su transient
non riusciva a trovare la sintassi! Ce n'è uno? non essendo in grado di ottenere una nuova istanza per ogni chiamata ottengo un'altra razza di strani errori che di solito risolverei con una vita transitoria
An attempt was made to use the context while it is being configured. A DbContext instance cannot be used inside OnConfiguring since it is still being configured at this point. This can happen if a second operation is started on this context before a previous operation completed. Any instance members are not guaranteed to be thread safe.
Anche a mio avviso il parametro poolsize in AddDbContextPool
sta semplicemente impostando la dimensione della cache per DbContext
oggetti DbContext
da riutilizzare e non impedisce in alcun modo il numero di connessioni totali. Mi piacerebbe che il pool fosse saturo per poter bloccare la successiva chiamata "get DBContext" fino a quando un'istanza diventa disponibile.
Quindi la mia domanda alla comunità è come risolvere questo problema? Mi piacerebbe ridurre il numero di istanze di DbContext
a un numero di correzione, ad es. 10, e averli memorizzati nella cache. Vorrei comunque configurare le opzioni per consentire i tentativi, ma ancora una volta, questi timeout si verificheranno per motivi esterni e non perché il mio codice sta creando centinaia di istanze che cercano di salvare piccoli messaggi nel database.
Non ero in grado di impostare l'ambito su transient non riusciva a trovare la sintassi! Ce n'è uno?
No, chiaramente perché la durata di DbContexts è controllata dalla cache.
Il messaggio di errore che ottieni è causato dall'accesso alla stessa istanza di DbContext da più thread perché la classe DbContext non è thread-safe. In effetti, significa che il tuo pool DbContext non funziona correttamente, probabilmente perché non stai creando un ambito quando consumi un messaggio dalla coda dei messaggi, quindi l'istanza di DbContext è condivisa su più thread. Questo ambito viene creato sotto la copertina in MVC quando arriva la richiesta HTTP, ma in un altro tipo di applicazione devi crearlo da solo.
Nota c'è anche una differenza tra il pool DbContext e il pool di connessioni. Se è necessario controllare il numero di connessioni dall'applicazione, è necessario utilizzare il pool di connessioni.
Come risolvere questo problema?
Non implicherei affatto il pool di contesti, preferirei piuttosto impostare un meccanismo di limitazione per controllare un numero di thread che consumano dalla tua coda.