asp.net-mvc - 雷迪斯 : New Keys not persisted in concurrent requests

标签 asp.net-mvc session concurrency redis

我们在我们的应用程序中集成了 Redis 缓存,在正常情况下工作正常。最近,我们在我们的应用程序中发现了一个非常奇怪的问题,即在并发 ajax 请求的情况下,新添加的键会自动删除,并且修改后的键具有旧值。 场景如下:

Ajax 请求 1: - 从数据库读取数据,大约需要 5-6 秒返回 - 在页面加载时触发(document.ready 事件)

Ajax 请求 2: - 触发按钮点击 - 在 session 中设置值 - 在 Ajax 请求 1 完成之前完成

Ajax 请求 3: - 简单地读取 session 值 - 找到旧值,应该已经收到 Ajax 请求 2 设置的值

所以这里的顺序是这样的:

1) Ajax Req 1 触发并开始处理,

2) Ajax Req 2 triggered , sets the values in session (modified existing as well as added a new key)

3) Ajax Req 2 完成

4) Ajax Req 1 完成

5) Ajax Req 3 被触发,得到了 Req 1 的旧值,应该接收到 Req 2 设置的值

最初我们认为一定有一些代码正在覆盖值,但没有找到这样的代码。

我尝试使用示例应用程序重现相同的案例,并且能够在那里看到类似的案例。 下面是源代码:

public JsonResult Test1()
        {
            Session["MyTest"] = "Vijay";
            SessionManager.ProposalRequestID = 1;
            SessionManager.VendorID = 2;

            return Json(new { reqID = SessionManager.ProposalRequestID, venID = SessionManager.VendorID, mytest = Session["MyTest"] }, JsonRequestBehavior.AllowGet);
        }

        public JsonResult Test2()
        {
            System.Threading.Thread.Sleep(3000);
            return Json(new { reqID = SessionManager.ProposalRequestID, venID = SessionManager.VendorID, mytest = Session["MyTest"] }, JsonRequestBehavior.AllowGet);
        }

        public JsonResult Test3()
        {
            return Json(new { reqID = SessionManager.ProposalRequestID, venID = SessionManager.VendorID, mytest = Session["MyTest"] }, JsonRequestBehavior.AllowGet);
        }

UI 如下所示:

<body>
    <div>
        <button id="btn1">Set Session</button>
        <button id="btn2">Heavy Task</button>
        <button id="btn3">Use Session</button>
    </div>
    <div style="color:red;height:500px;overflow-y:auto">
        <span id="message"></span>
    </div>
</body>

<script type="text/javascript">

    $(document).ready(function () {
        SendTestAjaxCall('@Url.Action("Test2")', "Heave Task");

        $('#btn1').click(function () { SendTestAjaxCall('@Url.Action("Test1")', "Set Session") });
        $('#btn2').click(function () { SendTestAjaxCall('@Url.Action("Test2")', "Heave Task") });
        $('#btn3').click(function () { SendTestAjaxCall('@Url.Action("Test3")', "User Session") });
    });

    function SendTestAjaxCall(URL, message) {
        addToLog("Sending request for  " + message);
        $.ajax({
            url: URL,
            success: function (result) {
                addToLog("Response from " + message, result);
            }
        });
    }

    function addToLog(message, data) {
        $("#message").html($("#message").html() + '<p>' + message + '</p>');
        if (data) {
            addToLog(JSON.stringify(data), null);
        }
    }

</script>

最佳答案

最后我找到了解决方案,它与 Redis 无关,但它与我们应用程序中的中间层有关,它管理来自同一用户的请求之间的锁定机制。我们发现这是基于 Redis 总是存储在键值对中的事实,它总是会更新存储中的最后一个给定值,但是我们的自定义中间层总是在请求结束时恢复 session ,因此最后结束的请求将恢复其 session 。 抱歉对 Redis 的无效疑问

关于asp.net-mvc - 雷迪斯 : New Keys not persisted in concurrent requests,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45326700/

相关文章:

asp.net - 在asp.net中使用过多 session 的缺点

session - PHPMyAdmin 自动 session 销毁问题

java - 卡在受信号量保护的交互中

c# - Azure AD graph api 在本地工作但在部署时失败

c# - .Net Mvc : How to fire a error for Application_Error() manage them?

asp.net-mvc - 在 mvc dotnetcore 中处理面包屑

javascript - 为什么我刷新页面时会得到一个新的 session (我在save()之后创建了 session )

go - 为什么以下 channel 操作会死锁?即下游<-<-上游

go - 如何在 Golang 中实现适当的并行性? goroutines 在 1.5+ 版本中是并行的吗?

asp.net-mvc - 使用将 Ajax 返回到 Ajax.BeginForm 的 onBegin 的函数