在 Ef Core 上调用 SaveChangesAsync 时出现以下错误 - 错误 0x80131904
Data modification failed on system-versioned table 'table name' because transaction
time was earlier at than period start time for affected records.
我知道此错误与历史表中的有效起始日期和有效截止日期有关,如果发生大量活动,则会导致重叠
我知道这个错误是设计使然,我无法真正避免它
但是,我需要一个解决方案,以便在发生异常时重试 SaveChangesAsync 调用,并显示此消息
我认为解决方案是在数据库初始化时
options.UseSqlServer(connectionString,
sqlOptions =>
{
sqlOptions.MigrationsAssembly(MigrationAssemblyName);
sqlOptions.EnableRetryOnFailure(maxRetryCount: 10,
TimeSpan.FromSeconds(30),
new List<int>()
{
80131904
});
sqlOptions.CommandTimeout(240);
});
参数
new List<int>()
{
80131904
};
但是,我不确定这是否正确,或者在这种情况下是否有更好的重试方法?
这个数字正确吗?它似乎是十六进制,但将其转换为数字会得到一个比 int 可以容纳的数字更大的数字
这个错误号似乎与错误消息没有具体关系,感觉这已经是一个被归类为瞬态的错误号?
错误号似乎是十六进制,但是当转换为十六进制时,它太大而无法存储为整数
有人有这方面的经验吗?
保罗
13535
而不是 80131904
(这只是 SqlException
的 HResult 的十六进制)。您可以在 exception.Number
属性中看到错误号。
options.UseSqlServer(connectionString,
sqlOptions =>
{
sqlOptions.MigrationsAssembly(MigrationAssemblyName);
sqlOptions.EnableRetryOnFailure(
maxRetryCount: 10,
TimeSpan.FromSeconds(30),
new []{ 13535 }
);
sqlOptions.CommandTimeout(240);
});
唯一的其他选择是使用某种锁定机制。例如,您可以在同一事务中添加显式命令
SELECT TOP (1) 1 AS dummy
FROM Table WITH (UPDLOCK, TABLOCK);
这将防止任何修改,同时仍然允许
SELECT
查询。
sp_getapplock
来控制对修改过程的访问:同样,这将阻止任何其他人尝试获得相同的锁,但允许任何不这样做的人。
请注意,此错误可能与其他交易无关。如果您对
DEFAULT
列的 PERIOD
约束不够精确,那么您可能会在自己的行上出现舍入错误。确保始终使用 SYSUTCDATETIME()
来防止出现问题。