Procesar miles de comandos SqlCommands usando una transacción Sql genera una excepción de memoria
-
12-12-2019 - |
Pregunta
Escribí una función de replicación personalizada en una aplicación de formularios de Windows C# estándar con una base de datos SQL Server 2008 Express.Básicamente, despliega un conjunto de declaraciones SQL que deben ejecutarse en una base de datos de suscriptores.En una actualización completa, esto puede ejecutar hasta más de 200.000 declaraciones que deben ejecutarse.
Proceso estas declaraciones dentro de un bloque de código como se muestra a continuación:
using (SqlConnection connection = ConnectionManager.GetConnection())
{
connection.Open();
SqlTransaction transaction = connection.BeginTransaction();
// Process 200k+ Insert/Update/Delete statements using SqlCommands
transaction.Commit
}
Lo que estoy encontrando es que el uso de memoria de mis aplicaciones se mantiene bastante estable en alrededor de 40 MB para las primeras declaraciones de 30 000.Después de lo cual, de repente parece saltar a alrededor de 300 MB y luego crece hasta que llego a una excepción OutOfMemory.
¿Es posible el método que estoy usando? ¿Puedo procesar tantas declaraciones dentro de una sola transacción?Supongo que debería poder hacer esto.Si hay una manera mejor, me encantaría verla aquí.Necesito que esto sea transaccional; de lo contrario, una replicación parcial daría como resultado una base de datos rota.
Gracias.
EDITAR:
Después de reiniciar mi computadora, logré realizar una replicación completa de más de 200k.Aunque en un momento el uso de la memoria aumentó a 1,4 Gb después de que se completó la replicación, el uso de la memoria volvió a caer a 40 MB.Lo que me lleva a concluir que algo dentro de mi bucle que procesa los comandos quizás esté provocando el crecimiento de la memoria.
Solución
Eres Disposing
¿Tus formularios y los controles desechables antes de cerrar?
Envuelva todos los objetos desechables en la declaración de uso.Haga clic aquí para más detalles
No abra/cierre la conexión una y otra vez; en su lugar, envíe los datos a la base de datos en una sola transacción.Haga clic aquí para más detalles
Aún así, su aplicación tiene demasiada memoria, entonces necesita un médico como Red Gate Ants Memory Profiler.Haga clic aquí para ver más detalles al respecto.
¿Puedo procesar tantas declaraciones dentro de una sola transacción?
Tienes las siguientes opciones para hacer esto...
- Insertar y operar de forma masiva los registros en
Stored Proc
. - Preparar
XML
y enviar la cadena enDatabase
. - Enviar el solo lectura
DataTable
en el servidor Sql a través de Stored Proc
Ejemplo de proceso almacenado
Begin Try
Set NoCount ON
Set XACT_Abort ON
Begin TRan
--Your queries
Commit Tran
Begin Tran
Begin Catch
Rollback Tran
End Catch
Asegurate que Dispose
los objetos una vez que no estén en uso.
debería ser así
using (SqlConnection connection = new SqlConnection())
{
connection.Open();
using (SqlTransaction transaction = connection.BeginTransaction())
{
transaction.Commit();
}
}
¿Verificaste el SqlCommand
¿también?
using (SqlCommand cmd = new SqlCommand())
{
}