writetoserver sqlbulkcopyoptions keepidentity bulkcopy batch c# sql-server transactions bulkinsert sqlbulkcopy

sqlbulkcopyoptions - c# sql server bulk copy



¿SqlBulkCopy inicia automáticamente una transacción? (1)

No aquí hay texto de la documentación de docs en docs

De forma predeterminada, una operación de copia masiva se realiza como una operación aislada. La operación de copia masiva se realiza de forma no transaccional, sin posibilidad de revertirla. Si necesita revertir toda o parte de la copia masiva cuando se produce un error, puede usar una transacción administrada por SqlBulkCopy , realizar la operación de copia masiva dentro de una transacción existente o inscribirse en una Transacción de Transacciones de Sistema.

EDITAR: Lea correctamente la documentación, desde el enlace que le di:

Por defecto, una operación de copia masiva es su propia transacción. Cuando desee realizar una operación de copia masiva dedicada, cree una nueva instancia de SqlBulkCopy con una cadena de conexión o use una
Objeto SqlConnection existente sin una transacción activa. En cada escenario, la operación de copia masiva crea y, a continuación, confirma o revierte la transacción.

Esto está escrito para la transacción de copia masiva interna del caso, que no es la predeterminada.

using (SqlBulkCopy bulkCopy = new SqlBulkCopy( connectionString, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.UseInternalTransaction)) { .... }

¡Mire de cerca en SqlBulkCopyOptions.UseInternalTransaction ! Está especificando explícitamente que la opción UseInternalTransaction en el constructor de la clase SqlBulkCopy causa explícitamente que una operación de copia masiva se ejecute en su propia transacción, lo que hace que cada lote de la operación de copia masiva se ejecute dentro de una transacción separada. Desde que se ejecutan lotes diferentes en transacciones diferentes Si se produce un error durante la operación de copia masiva, todas las filas del lote actual se revertirán, pero las filas de los lotes anteriores permanecerán en la base de datos.

Si necesita revertir toda la operación de copia masiva porque se produce un error, o si la copia masiva debería ejecutarse como parte de un proceso mayor que puede revertirse, puede proporcionar un objeto SqlTransaction al constructor SqlBulkCopy.

El caso de la transacción externa.

using (SqlTransaction transaction = destinationConnection.BeginTransaction()) { using (SqlBulkCopy bulkCopy = new SqlBulkCopy( destinationConnection, SqlBulkCopyOptions.KeepIdentity, transaction)) { .... } }

Como dije en la solicitud, la respuesta es no, debe usar una transacción existente o una transacción de copia masiva interna. Lea el archivo de documentación que se encuentra en el enlace, para obtener más información.

Si desea realizar una transacción, debe utilizar uno de los dos casos que escribí.

Estoy insertando datos a través de SqlBulkCopy así:

public void testBulkInsert(string connection, string table, DataTable dt) { using (SqlConnection con = new SqlConnection(connection)) { con.Open(); using (SqlBulkCopy bulkCopy = new SqlBulkCopy(con)) { bulkCopy.DestinationTableName = table; bulkCopy.WriteToServer(dt); } } }

¿Se incluirá esto automáticamente en una transacción de SQL, de modo que si algo sale mal a mitad de la base de datos, se dejará en el mismo estado que tenía antes de que comenzara la inserción masiva? ¿O se insertará la mitad de los datos?

es decir, es necesario que llame explícitamente a con.BeginTransaction

O si llamo SqlBulkCopy constructor de SqlBulkCopy que toma una cadena, ¿es esa una mejor manera de hacer que ocurra en una transacción?

public void testBulkInsert(string connection, string table, DataTable dt) { using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection)) { bulkCopy.DestinationTableName = table; bulkCopy.WriteToServer(dt); } }

Encuentro la docs un poco poco clara sobre este asunto, ya que inicialmente afirman que

De forma predeterminada, una operación de copia masiva se realiza como una operación aislada. La operación de copia masiva se realiza de forma no transaccional, sin posibilidad de revertirla

pero luego declara

Por defecto, una operación de copia masiva es su propia transacción. Cuando desee realizar una operación de copia masiva dedicada, cree una nueva instancia de SqlBulkCopy con una cadena de conexión, o use un objeto SqlConnection existente sin una transacción activa. En cada escenario, la operación de copia masiva crea y, a continuación, confirma o revierte la transacción.

Entonces es necesario hacer:

public void testBulkInsert(string connection, string table, DataTable dt) { using (SqlConnection con = new SqlConnection(connection)) { con.Open(); using (SqlTransaction tr = con.BeginTransaction(IsolationLevel.Serializable)) { using (SqlBulkCopy bulkCopy = new SqlBulkCopy(con, SqlBulkCopyOptions.Default, tr)) { bulkCopy.DestinationTableName = table; bulkCopy.WriteToServer(dt); } tr.Commit(); } } }