TransactionScope «Корневая внешняя транзакция была завершена до вложенной транзакции»C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 TransactionScope «Корневая внешняя транзакция была завершена до вложенной транзакции»

Сообщение Anonymous »

Вот мой сценарий:
У меня есть очень большая таблица в Microsoft Access, которую мне нужно переместить на SQL Server.

Код: Выделить всё

public async Task Sync()
{
using TransactionScope trans = new(TransactionScopeOption.Required, new TransactionOptions()
{
IsolationLevel = IsolationLevel.ReadCommitted,
Timeout = TimeSpan.FromMinutes(60),
}, TransactionScopeAsyncFlowOption.Enabled);
var options = new DbContextOptionsBuilder()
.UseSqlServer(Environment.GetEnvironmentVariable("CS") ?? throw new Exception("CS envar not defined"))
.Options;
await using var context = new FlushpanelContext(options
);
context.Database.SetCommandTimeout(TimeSpan.FromHours(1));
await context.Database.OpenConnectionAsync();
try
{
await using OleDbConnection mydb1 = new($@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={its2000Path};");
await mydb1.OpenAsync();

var partsService = new AccessPartsService(context, its2000Cn, logger);
await partsService.SyncPartsAsync();
trans.Complete();
}
finally
{
await context.Database.CloseConnectionAsync();
}
}

public async Task SyncPartsAsync()
{
// Get all of the parts from access
var accessParts = await accessCn.QueryAsync("SELECT * FROM parts WHERE Imported = 0");
logger.WriteLine($"{accessParts.Count()} parts to be imported in access", Color.DarkBlue);
var partTypes = await context.PartType
.Where(x => x.AccessTableId != null && x.AccessId != null)
.ToDictionaryAsync(x => (x.AccessTableId!.Value, x.AccessId!.Value));
var tablePartTypes = await context.PartType.Where(x => x.AccessTableId == null && x.AccessId == null)
.ToDictionaryAsync(x => x.Title);
await ProcessBatch(accessParts, alreadyExistingSqlParts, manufacturers, partTypes, tablePartTypes);
logger.WriteLine("Saving changes", Color.Purple);
await context.SaveChangesAsync();
await accessCn.ExecuteAsync("UPDATE parts SET Imported = 1 WHERE Imported = 0");
//await transaction.CommitAsync();
}

private async Task ProcessBatch(IEnumerable accessParts, Dictionary alreadyExistingSqlParts, FrozenDictionary manufacturers,
Dictionary partTypes, Dictionary tablePartTypes)
{
// This will run for about 300,000 parts
foreach (var accessPart in accessParts)
{
var converted = accessPart.ToPart(manufacturers);
context.Part.Add(converted);
logger.WriteLine($"Added part {accessPart.Part_ID}", Color.DarkGreen);
}
}
Я импортирую около 300 000 деталей. Этот код работает нормально, если я импортирую только 1000 записей. Однако, если я попытаюсь сделать все это, я получу следующую ошибку в await context.SaveChangesAsync(). Я попытался поместить SaveChanges в foreach, но ближе к концу возникает та же проблема... Очень странно и неприятно, поскольку это занимает около 20 минут, поэтому отладка кажется невозможной:

Код: Выделить всё

TransactionScope "A root ambient transaction was completed before the nested transaction"
Я установил большие тайм-ауты, поэтому не знаю, что происходит не так.

Подробнее здесь: https://stackoverflow.com/questions/784 ... nested-tra
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»