L'elaborazione di migliaia di comandi SqlCommand utilizzando SqlTransaction provoca un'eccezione di memoria
-
12-12-2019 - |
Domanda
Ho scritto una funzione di replica personalizzata in un'app Windows Form C# standard con un database SQL Server 2008 Express.Fondamentalmente estrae una serie di istruzioni SQL che devono essere eseguite su un database di abbonati.Con un aggiornamento completo è possibile eseguire fino a 200.000+ istruzioni che devono essere eseguite.
Sto elaborando queste istruzioni all'interno di un blocco di codice come mostrato di seguito:
using (SqlConnection connection = ConnectionManager.GetConnection())
{
connection.Open();
SqlTransaction transaction = connection.BeginTransaction();
// Process 200k+ Insert/Update/Delete statements using SqlCommands
transaction.Commit
}
Quello che sto scoprendo è che l'utilizzo della memoria delle mie applicazioni rimane abbastanza stabile a circa 40 MB per le prime istruzioni da 30.000.Dopo di che sembra improvvisamente passare a circa 300 MB e poi crescere fino a quando non si verifica un'eccezione OutOfMemory.
Il metodo che sto utilizzando è possibile, posso elaborare così tante dichiarazioni all'interno di una singola transazione?Presumo che dovrei essere in grado di farlo.Se c'è un modo migliore mi piacerebbe qui.Ho bisogno che questo sia transazionale, altrimenti una replica parziale comporterebbe un database danneggiato.
Grazie.
MODIFICARE:
Dopo aver riavviato il computer sono riuscito a eseguire una replica completa di oltre 200.000.Anche se a un certo punto l'utilizzo della memoria è aumentato fino a 1,4 Gb dopo il completamento della replica, l'utilizzo della memoria è sceso fino a 40 MB.Il che mi porta a concludere che qualcosa all'interno del mio ciclo che elabora i comandi sta forse causando la crescita della memoria.
Soluzione
Sei Disposing
i vostri moduli e i controlli usa e getta prima della chiusura?
Avvolgi tutti gli oggetti usa e getta nella dichiarazione Using.Clicca qui per maggiori dettagli
Non aprire/chiudere la connessione più e più volte, invia invece i dati al database in un'unica transazione.Clicca qui per maggiori dettagli
La tua applicazione contiene ancora troppa memoria, quindi hai bisogno di un dottore come Red Gate Ants Memory Profiler.Clicca qui per vedere maggiori dettagli a riguardo
posso elaborare così tante dichiarazioni all'interno di una singola transazione?
Di seguito sono disponibili le opzioni per farlo...
- Inserisci e gestisci in blocco i record
Stored Proc
. - Preparare
XML
e invia la stringaDatabase
. - Invia la sola lettura
DataTable
nel server SQL tramite Stored Proc
Proc. memorizzato campione
Begin Try
Set NoCount ON
Set XACT_Abort ON
Begin TRan
--Your queries
Commit Tran
Begin Tran
Begin Catch
Rollback Tran
End Catch
Assicurati che Dispose
gli oggetti una volta non utilizzati.
Dovrebbe essere così
using (SqlConnection connection = new SqlConnection())
{
connection.Open();
using (SqlTransaction transaction = connection.BeginTransaction())
{
transaction.Commit();
}
}
Hai verificato il SqlCommand
Anche?
using (SqlCommand cmd = new SqlCommand())
{
}