C #: Errores de conexión al abrir SqlConnection dentro de Parallel.ForEach

.net-core c# dapper parallel.foreach parallel-processing

Pregunta

Tengo una aplicación de consola .NET Core C # que realiza una gran cantidad de cálculos y luego escribe los resultados en una base de datos de edición de SQL Server 2016 Developer utilizando Dapper (y Dapper.Contrib). El problema que tengo es que cuando ejecuto muchos elementos en paralelo (más de 1000, por ejemplo), empiezo a recibir fallas de conexión intermitentes en la llamada .Open() , diciendo

Se ha producido un error relacionado con la red o un caso específico ...

Esto sucede a menudo después de que miles de filas ya se hayan insertado correctamente.

Una versión simplificada del código se vería así:

        Parallel.ForEach(collection, (item) =>
        {
                var results = item.Calculate(parameters);

                dal.Results.Insert(results);

                allResults.AddRange(results);
        });

Y dentro del método Insert, se ve así:

    public override void Insert(IEnumerable<Result> entities)
    {
        using (var connection = GetConnection())
        {
            connection.Open();

            using (var transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted))
            {
                connection.Insert(entities, transaction);

                transaction.Commit();
            }
        }
    }

Algunas otras cosas sobre el código que no creo que afecten a esto, pero podrían ser relevantes:

  • dal.Results es simplemente un repositorio que contiene ese método Insert() y está preinicializado con una cadena de conexión que se usa para instanciar una new SqlConnection(connectionString) cada vez que se llama a GetConnection() .

  • allResults es un ConcurrentBag<Result> que estoy usando para almacenar todos los resultados para su uso posterior fuera de Parallel.ForEach

  • Estoy usando una transacción porque parece funcionar mejor de esta manera, pero estoy abierto a sugerencias si eso podría estar causando problemas.

¡Gracias de antemano por cualquier orientación sobre este tema!

Respuesta aceptada

No hay ninguna ventaja para ejecutar operaciones db fuertemente enlazadas a IO en paralelo.

Debería crear fiebre pero grandes grupos de datos para insertar con una cantidad mínima de transacciones en la base de datos. Eso se puede lograr de varias maneras:

Así que intente seguir: Ejecute cálculos intensivos de CPU en bucle paralelo y guarde todos los resultados en la base de datos después del bucle.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué