ASP.NET请假管理系统同日期时间重复插入请假申请问题求助
解决方案
问题根因
偶发重复插入的核心原因是同步发送邮件导致接口响应速度慢,用户感知到页面卡顿后重复点击提交按钮,触发了多次提交请求,每次请求都会执行一次数据库插入逻辑,最终产生重复数据。你之前新增的成功判断逻辑本身没有问题,但无法拦截多次独立的提交请求。
三层修复方案
前端层(第一道防线)
点击提交按钮后立刻禁用按钮,直到请求结束后再恢复,从操作侧避免用户重复点击触发多次请求。示例代码:
// 绑定提交按钮点击事件 document.getElementById('duration').addEventListener('click', function() { // 点击后立刻禁用按钮 this.disabled = true; })
如果后端返回提交失败,再重新启用按钮方便用户重试即可。
后端逻辑优化(第二道防线)
把同步发邮件改为异步发送,不要阻塞主请求流程,大幅降低接口响应时间,从根源减少用户重复点击的可能。修改后的后端核心逻辑示例:
protected void duration_Click(object sender, EventArgs e) { // 原有参数赋值逻辑保持不变 srcLeaveDetails.InsertParameters["Leave_Id"].DefaultValue = txtleaveid.Text; srcLeaveDetails.InsertParameters["Leave_EmpId"].DefaultValue = txtempid.Text; // 其余参数赋值部分和原有代码一致,无需修改 bool flag = false; try { srcLeaveDetails.Insert(); flag = true; Label14.Text = "Your Leave Request has been recorded"; } catch (SqlException s) { Label14.Text = " Error! Please Try Again"; // 插入失败时恢复按钮可点击 duration.Enabled = true; return; } if(flag==true) { // 异步执行发邮件逻辑,不阻塞主请求返回 Task.Run(() => { sendMail(); }).ConfigureAwait(false); } }
注意异步发邮件时要在sendMail方法内做好异常捕获和日志记录,避免后台线程异常影响主进程稳定性。
数据库层(最后一道兜底防线)
给请假申请表加联合唯一约束,即使前两层逻辑都失效,数据库也会直接拒绝重复数据插入。示例SQL:
ALTER TABLE LeaveDetails ADD CONSTRAINT UNQ_Emp_Leave UNIQUE (Leave_EmpId, Leave_StartDate, Leave_EndDate, Leave_Type);
加了该约束后,重复插入请求会抛出唯一键冲突异常,你可以在catch中单独捕获该类异常,直接返回「该请假申请已提交」的提示即可。
内容的提问来源于stack exchange,提问作者User
相关产品推荐
相关产品推荐

