SQLBulkCopy causando interbloqueo

c# deadlock sqlbulkcopy sql-server

Pregunta

Tengo el siguiente código ... que en realidad inserta datos en el destino usando SQLBulkCopy. Este código falla en el servidor SQL de origen a menudo debido a un interbloqueo. Para su información, la tabla que se está copiando puede estar en uso (me refiero a que algunas inserciones / selecciones se estarían ejecutando) mientras realizamos una copia masiva.

¿Es eso lo que está causando el problema o la sugerencia "TABLOCK" tiene algo que ver? Según mi entendimiento, TABLOCK adquiere solo bloqueos compartidos y no debería ser un problema.

using (var reader = srcConnection.ExecuteReader($"select * from [{DatabaseName}].[{schemaName}].[{tableName}]"))
{
    const SqlBulkCopyOptions bulkCopyOptions = SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.FireTriggers |
                                               SqlBulkCopyOptions.KeepNulls | //Do not replace nulls with defaults in destination
                                               SqlBulkCopyOptions.KeepIdentity;
        //Use the identity values from source, do not generate identities in destination.

    using (var bcp = new SqlBulkCopy(dstConnection.ConnectionString, bulkCopyOptions))
    {
        const int threeMinutes = 60*3;

        bcp.BulkCopyTimeout = threeMinutes; //Timeout is for a single batch
        bcp.BatchSize = 5000;
        bcp.DestinationTableName = $"[{DestinationDatabaseName}].[{schemaName}].[{tableName}]";
        bcp.EnableStreaming = true;

        foreach (var col in table.Columns.Cast<Column>().Where(c => !c.Computed))
        {
            bcp.ColumnMappings.Add(col.Name, col.Name);
        }

        bcp.WriteToServer(reader);
    }
}

Respuesta popular

La inserción masiva deberá insertar filas en la tabla. Insertar filas requiere bloqueos exclusivos. Los bloqueos exactos adquiridos dependerán del modelo de concurrencia.

Si especifica la opción TableLock , su proceso intentará adquirir un bloqueo de tabla exclusivo. Esto definitivamente puede llevar a puntos muertos si su proceso adquiere primero un bloqueo de tabla compartido, otro proceso tiene bloqueos de fila compartidos, y ambos procesos intentan actualizar sus bloqueos a bloqueos exclusivos.

Hay varias formas de obtener más información sobre los puntos muertos:



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é