SQLBulkCopy che causa deadlock

c# deadlock sqlbulkcopy sql-server

Domanda

Ho il seguente codice ... che in realtà inserisce i dati nella destinazione usando SQLBulkCopy. Questo codice non funziona correttamente nel server SQL di origine a causa di deadlock. Per vostra informazione, la tabella che si sta copiando può essere in uso (intendevo che alcuni inserti / selezioni sarebbero in esecuzione) mentre eseguiamo la copia di massa.

Quello che sta causando il problema o il suggerimento "TABLOCK" ha qualcosa da fare? Secondo la mia comprensione, TABLOCK acquisisce solo blocchi condivisi e non dovrebbe essere 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);
    }
}

Risposta popolare

L'inserto di massa dovrà inserire righe nella tabella. L'inserimento di righe richiede blocchi esclusivi. I blocchi esatti acquisiti dipenderanno dal modello di concorrenza.

Se si specifica l'opzione TableLock , il processo tenterà di acquisire un blocco tabella esclusivo. Questo può sicuramente portare a deadlock se il processo prima acquisisce un blocco di tabella condivisa, altri processi hanno blocchi di riga condivisi e entrambi i processi cercano di aggiornare i loro blocchi a blocchi esclusivi.

Esistono diversi modi per ottenere maggiori informazioni sui deadlock:



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow