我有一个端点,它将一些实体称为POST,称为Entry。这些条目有一个名为OrderNumber的属性,它是根据今天已经发生的条目确定的1-n数字。因此,当当前数据库中有100个条目时,新的OrderNumber应为101。
那么当你从不同的设备(X和Y)两次击中端点时会发生什么:
X.发送条目
X.向数据库询问当前条目 - >响应为100
Y.发送一个条目
Y.询问数据库当前条目 - >响应100
X.将使用OrderNumber 101插入记录
Y. Record将与OrderNumber 101一起插入
我的解决方案是创建一个带队列的后台任务(如下所示:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.1#queued-background-tasks)并在那里创建条目以确保它们一个接一个地处理。
现在我的控制器中的问题是,我无法在请求期间使用正确的OrderNumber返回最新的条目,因为只要队列处理了此条目,它就会发生。
那么客户如何正确地获得响应?或者有更好/不同的方式来处理这些案件?
自定义属性代码:
public class SingleThreadAttribute : ActionFilterAttribute
{
private static Object _thisLock = new Object();
public override void OnActionExecuting(ActionExecutingContext context)
{
Monitor.Enter(_thisLock);
base.OnActionExecuting(context);
}
public override void OnActionExecuted(ActionExecutedContext context)
{
base.OnActionExecuted(context);
Monitor.Exit(_thisLock);
}
}
通过在控制器的动作端点上添加[SingleThread]
属性,如果同时进行多次调用,则在等待前一次调用释放锁定时,它们将处理一个。
这可能是您案件的解决方案。
我刚刚发现这个stackoverflow的答案似乎解决了我的问题:
How to protect resources that may be used in a multi-threaded or async environment?