In-Memory-Datenbank mag kein Zwei-Phasen-Commit
Posted: 08 Feb 2025, 04:23
Mein datenbankabhängiger Code wird mit einer SQLite-In-Memory-Datenbank verspottet, während die Produktionslaufzeit in Umgebungen wie Microsoft SQL Server, IBM DB2, Oracle-Datenbank oder Sybase. > Ich versuche, eine zweiphasige-Commit-Prozedur für ein Aktionsprotokoll zu erstellen, das gespeichert wird, wenn ein damit verbundener Datenbankkontext gespeichert ist. Manchmal erfolgen die Änderungen in derselben Datenbank, in der sich die Aktionsprotokolltabellen befinden. Wenn ich Transaktionen gegen eine SQLite-In-Memory-Datenbank öffne und versuche, Context2 nach dem Speichern von Context1 zu speichern, wird nach etwa 30 Sekunden eine Ausnahme ausgelöst:
SQLite -Fehler 6: 'Die Datenbanktabelle ist gesperrt'. in ReadCommited (a.k.a. "Dirty Read") ändern, andernfalls würde das Schloss bereits auf context2.Employees.tolist () .
Ist es ein Muss, Transaktionen zu verpflichten/rollen, um anschließend mit Transaktionen umgegangen zu werden, auch wenn sie an verschiedenen Unternehmen arbeiten?
SQLite -Fehler 6: 'Die Datenbanktabelle ist gesperrt'.
Code: Select all
var connectionString = $"Data Source=file:{DatabaseAlias};mode=memory;cache=shared";
optionsBuilder.UseSqlite(connectionString);
< /code>
Der 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>
Transaktionshandhabung: < /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>
Die beiden Kontexte ändern Daten zu verschiedenen Entitäten, aber immer noch eine Kollision. Ich musste die Standard -IsolationLevel
Ist es ein Muss, Transaktionen zu verpflichten/rollen, um anschließend mit Transaktionen umgegangen zu werden, auch wenn sie an verschiedenen Unternehmen arbeiten?