在客户端或服务器端排队更新数据的请求?

Queueing of requiests to update data on client or server side?

所以我有一个带有可排序列的网格。在每次排序时,都会有一个像 UpdataGridSorting 这样的操作向服务器发送新数据 POST 请求。

在服务器上,有一种更新数据库中数据的方法。它以一种非常糟糕的方式做到这一点:没有锁来防止数据库中的同时数据更新,只有锁用于更新时读取。

因此我遇到了一个问题:当用户多次点击排序时,发送了多个请求,它们可能会同时覆盖数据并创建脏数据。

所以我的解决方法是在某侧对请求进行排队,并且在上一次更新完成之前不更新数据库。在哪边创建队列比较好?

现在我的意图是:

saveGridColumnSorting = (dataToSend, action, forceSend) ->
    if not forceSend
        queue.enqueue(dataToSend.id);
    if queue.lenght > 1 and not forceSend
        return
    $.ajax(
            url: url + "/" + action,
            data: dataToSend,
            success: (data) ->
                if (queue.lenght > 0)
                    saveGridColumnSorting(queue.dequeue());
        )
    return

此外,如果您能看到 XY 问题,请参考有助于修复您答案中的 X 的模式或任何可信赖的来源。

特别是如果系统是为多个用户设计的(就像你在评论中所说的那样),那么这样做就存在明显的风险client-side。对于初学者来说,这是一个安全漏洞。其次,当不止一个用户发出这些呼叫时会发生什么?

所以它肯定会发生在服务器上。同时,也许为这样的任务使用队列不是最明智的选择,因为通过这样做,一个用户可以很容易地为其他人创建一个 denial-of-service,通过填满队列,甚至导致整个由于内存不足而崩溃的东西。

还有一个问题是,当用户 A 请求以一种方式对其进行排序时会发生什么,然后,在数据库 re-read 之前,用户 B 提交了他们自己的排序请求,该请求已被处理。第一个用户不会得到错误的输出,可能他们并没有意识到吗?

为避免所有这些问题——前提是在内存和其他可能未提供的信息方面是可能的——您可以选择保留 result-set 的缓存副本,您可以将其排序 per-request,而不是修改实际的数据库。或者,如果数据库引擎可以以 read-only 的方式自行进行排序,那么就应该使用这种方式。

好吧,在客户端有一个队列的方案证明了它在行动中是有效的。但是,找到了一个替代方案:在用户执行某些操作时及时阻止 UI。列排序不是很好的体验,但仍然比排队请求更安全。在服务器端排队会导致复杂性增加,尤其是对于 MVC 应用程序。