1

我有多个 API 客户端调用 TokenAuth/Authenticate 来获取使用 API 的访问令牌。当他们尝试这个太靠近彼此时,我在 TokenAuthController/Autheticate 中的 GetLoginResultAsync 处遇到并发冲突。

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

为什么,我应该如何解决这个问题?

4

1 回答 1

1

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

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

这发生在使用乐观锁定时。并且 AspnetBoilerplate 使用该方法针对悲观锁定的性能优先级。

解决方案:在您的 TokenAuthController 类中修改 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

于 2017-08-11T06:37:02.300 回答