База данных в памяти не любит двухфазный коммитC#

Место общения программистов C#
Ответить
Anonymous
 База данных в памяти не любит двухфазный коммит

Сообщение Anonymous »

Мой код, зависящий от базы данных, высмеивается в отношении базы данных в памяти SQLite, в то время как время выполнения производства может произойти в таких средах, как Microsoft SQL Server, IBM DB2, Oracle Database или Sybase. < /p>
Я пытаюсь создать двухфазной процедуры для журнала действий, который сохраняется, когда контекст базы данных, связанный с ним, сохраняется. Иногда изменения происходят в той же базе данных, где находятся таблицы журналов действий. Когда я открываю транзакции против базы данных SQLite в памяти и пытаюсь сохранить Context2 после сохранения контекста1 , исключение бросается через 30 секунд:

Ошибка SQLite 6: 'Таблица базы данных заблокирована'.

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

var connectionString = $"Data Source=file:{DatabaseAlias};mode=memory;cache=shared";
optionsBuilder.UseSqlite(connectionString);
< /code>
test: < /p>
var context1 = factory.CreateDbContext();
var context2 = factory.CreateDbContext();
context1.WithTransaction(() =>
{
var keysFromContext1 = context1.Keys.ToList();
keysFromContext1.First().Name = "Changed First";
context2.WithTransaction(() =>
{
var employeesFromContext2 = context2.Employees.ToList();
employeesFromContext2.First().Name = "Changed Second";
context1.SaveChanges();
context2.SaveChanges();
});
});
< /code>
Обработка транзакций: < /p>
public void WithTransaction(Action action)
{
WithTransaction(action, IsolationLevel.ReadUncommitted);
}

public void WithTransaction(Action action, IsolationLevel isolationLevel)
{
if (Database.CurrentTransaction != null)
{
action();
return;
}
Database.BeginTransaction(isolationLevel);
try
{
action();
Database.CommitTransaction();
}
catch
{
Database.RollbackTransaction();
throw;
}
}
< /code>
Два контекста изменяют данные на разных объектах, но все же появляется столкновение. Мне пришлось изменить изоляцию по умолчанию 
на readuncommited (a.k.a. "Dirty Read"), в противном случае блокировка уже произойдет на контексте2.employees.tolist () .
Необходим ли транзакции по совершению/откат, чтобы впоследствии запустили обработанные транзакции, даже если они работают на разных объектах?

Подробнее здесь: https://stackoverflow.com/questions/794 ... ase-commit
Ответить

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

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

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

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

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