多个 API 客户端在验证时发生并发冲突

Multiple API clients get concurrency conflict on auth

我有多个 API 客户端调用 TokenAuth/Authenticate 来获取使用 API 的访问令牌。当他们彼此之间的距离太近时,我在 TokenAuthController/Autheticate.

中的 GetLoginResultAsync 处发生了并发冲突

完整异常消息:数据库操作预计会影响 1 行,但实际上影响了 0 行。自加载实体以来,数据可能已被修改或删除。有关理解和处理乐观并发异常的信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=527962

为什么,我该如何解决?

(我猜你的不同客户使用同一个帐户登录。)

一般异常说明;从数据库中获取一个实体,然后另一个客户端获取相同的实体。第二个客户端更新实体并提交给数据库。当第一个客户试图保存实体时,他有一个过时的脏实体。因此你得到了并发冲突!

这发生在Optimistic Locking is used. And AspnetBoilerplate uses that method for performance priority against Pessimistic Locking

解决方法: 在您的 TokenAuthController class 中修改 Authenticate 方法;

private static AsyncLock _asyncLock = new AsyncLock();

[HttpPost]
public async Task<AuthenticateResultModel> Authenticate([FromBody] AuthenticateModel model)
{
    //i am using AsyncLock because there are async methods in Authenticate.
    using (await _asyncLock.LockAsync())
    {
        var loginResult = await GetLoginResultAsync(
            model.UserNameOrEmailAddress,
            model.Password,
            GetTenancyNameOrNull()
        );
        
        //other codes ...
    }
}

对于 AsyncLock 库,请参阅 https://github.com/StephenCleary/AsyncEx