从 table 到 Entity Framework Core 的条目(检索和删除)的隔离事务?
An isolated transaction to (retrieve and delete) an entry from a table through Entity Framework Core?
为了形象化——天真地——如果我想完成这样的操作,我可能会使用下面的代码。
假设 dbContext
和 dbContext.Entries
分别属于 DbContext
(PostgreSQL) 和 DbSet<Entry>
类型。
var entry = await dbContext.Entries.FindAsync(key);
dbContext.Entries.Remove(entry);
await dbContext.SaveChangesAsync();
return entry;
但是,如果这段代码是由两个或多个进程并发执行的,我认为它可能不是完全隔离的(如果我错了请指正)。例如,两个进程首先从第一行接收相同的条目,然后将其删除。尽管该条目仍将被正确删除,但两个进程都会收到该条目,这违反了隔离规则。
我想知道是否可以使用 EF Core 来处理这种情况,以便每个事务都与其他事务完全隔离?
我从研究中发现的一种方法是用显式事务语句(docs) and change the isolation level if needed. However, from the docs of DbSet.FindAsync()
,如果“给定的”,则不会对数据库进行查询上下文正在跟踪主键值。"
而且我不确定 DbSet.FindAsync()
操作是否会像修改操作(例如 DbSet.Remove()
、DbSet.Add()
)一样在明确声明的事务中按顺序考虑。
如果我的任何假设有误,请纠正我,在此先感谢!
编辑:抱歉提及;我将 PostgreSQL 与 EF Core 结合使用。
如果 entity framework 尝试修改或删除丢失或最近更新的记录,它将抛出 DbUpdateConcurrencyException
。
DbUpdateConcurrencyException
Exception thrown by DbContext when it was expected that SaveChanges for an entity would result in a database update but in fact no rows in the database were affected. This usually indicates that the database has been concurrently updated such that a concurrency token that was expected to match did not actually match
因此您可以将代码包装在 try catch 中并捕获该异常。
try
{
var entry = await dbContext.Entries.FindAsync(key);
dbContext.Entries.Remove(entry);
await dbContext.SaveChangesAsync();
return entry;
}
catch(DbUpdateConcurrencyException e)
{
// do something with e
}
catch(Exception e)
{
// if something else happens, like null reference
}
为了形象化——天真地——如果我想完成这样的操作,我可能会使用下面的代码。
假设 dbContext
和 dbContext.Entries
分别属于 DbContext
(PostgreSQL) 和 DbSet<Entry>
类型。
var entry = await dbContext.Entries.FindAsync(key);
dbContext.Entries.Remove(entry);
await dbContext.SaveChangesAsync();
return entry;
但是,如果这段代码是由两个或多个进程并发执行的,我认为它可能不是完全隔离的(如果我错了请指正)。例如,两个进程首先从第一行接收相同的条目,然后将其删除。尽管该条目仍将被正确删除,但两个进程都会收到该条目,这违反了隔离规则。
我想知道是否可以使用 EF Core 来处理这种情况,以便每个事务都与其他事务完全隔离?
我从研究中发现的一种方法是用显式事务语句(docs) and change the isolation level if needed. However, from the docs of DbSet.FindAsync()
,如果“给定的”,则不会对数据库进行查询上下文正在跟踪主键值。"
而且我不确定 DbSet.FindAsync()
操作是否会像修改操作(例如 DbSet.Remove()
、DbSet.Add()
)一样在明确声明的事务中按顺序考虑。
如果我的任何假设有误,请纠正我,在此先感谢!
编辑:抱歉提及;我将 PostgreSQL 与 EF Core 结合使用。
如果 entity framework 尝试修改或删除丢失或最近更新的记录,它将抛出 DbUpdateConcurrencyException
。
DbUpdateConcurrencyException
Exception thrown by DbContext when it was expected that SaveChanges for an entity would result in a database update but in fact no rows in the database were affected. This usually indicates that the database has been concurrently updated such that a concurrency token that was expected to match did not actually match
因此您可以将代码包装在 try catch 中并捕获该异常。
try
{
var entry = await dbContext.Entries.FindAsync(key);
dbContext.Entries.Remove(entry);
await dbContext.SaveChangesAsync();
return entry;
}
catch(DbUpdateConcurrencyException e)
{
// do something with e
}
catch(Exception e)
{
// if something else happens, like null reference
}