【发布时间】:2018-01-01 18:16:18
【问题描述】:
我们在我们的应用程序中集成了 Redis 缓存,在正常情况下运行良好。最近我们在我们的应用程序中发现了一个非常奇怪的问题,即在并发 ajax 请求的情况下,新添加的键会被自动删除,而修改的键具有旧值。 场景如下:
Ajax 请求 1: - 从数据库读取数据,大约需要 5-6 秒才能返回 - 在页面加载时触发(document.ready 事件)
Ajax 请求 2: - 触发按钮点击 - 在会话中设置值 - 在 Ajax 请求 1 完成之前完成
Ajax 请求 3: - 只需读取会话值 - 找到旧值,应该已经收到 Ajax 请求 2 设置的值
所以这里的顺序是这样的:
1) Ajax Req 1 触发并开始处理,
2) Ajax Req 2 触发,设置会话中的值(修改现有以及添加新键)
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);
}
用户界面如下:
<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>
【问题讨论】:
-
在 ajax 中添加 async :false 并告诉我结果。
-
async: false 将起作用,因为它将开始同步处理请求,但随后它将开始显示性能问题,这对我来说又是一个新问题。
-
你有什么解决办法吗?
标签: asp.net-mvc session concurrency redis