多个 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
我有多个 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