Я вставляю данные через SqlBulkCopy
следующим образом:
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);
}
}
}
Будет ли это автоматически обернуто в транзакцию SQL, так что если что-то пойдет не так, на полпути через БД будет оставлено то же состояние, что и до начала массовой вставки? Или половина данных будет вставлена?
то есть. мне необходимо явно называть con.BeginTransaction
Или, если я вызываю конструктор SqlBulkCopy
, который принимает строку, является ли лучший способ заставить его произойти в транзакции?
public void testBulkInsert(string connection, string table, DataTable dt)
{
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
{
bulkCopy.DestinationTableName = table;
bulkCopy.WriteToServer(dt);
}
}
Я нахожу docs немного неясным в этом вопросе, поскольку они изначально заявляют, что
По умолчанию операция массового копирования выполняется как изолированная операция. Операция массовой копии выполняется неконтактным способом, без возможности перевернуть его назад
но затем состояние
По умолчанию операция массового копирования является собственной транзакцией. Когда ты хотите выполнить выделенную операцию массовой копии, создать новый экземпляр SqlBulkCopy с строкой подключения или использовать существующую Объект SqlConnection без активной транзакции. В каждом сценарии, операция массового копирования создает, а затем совершает или откатывает сделка.
Так что это необходимо сделать:
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();
}
}
}