asp.net 数据重复并发提交问题解决方案

datahandler2 2016-03-17 12:54:07
开发了一个MVC系统,这个系统编写了一个开放的API方法接口,方法如下:

public class PaySettlementCenter:Controller
{
[Httppost]
public static JsonResult Pay(PayOrder payOrder)
{
var orderNO=payOrder.OrderNO;

// 查询数据库是否存在该笔订单号,存在则不插入
}
}

那么问题是,调用方那边在他们的系统作业线程里面调用这个接口的时候,我无法准确确认是啥原因,偶尔会出现同样一笔订单(相同订单号)会同时并发通过我系统这个方法在我数据库里面插入两笔重复的相同订单号。。。无论我这个系统里面是否有实时查询数据库是否存在该笔订单号还是会存在重复插入的问题。。。。
想了几个解决方法不知道哪个比较合适可以防止并发问题:
A。每次进入Pay这个方法就判断 订单号是否有在缓存key里面,有则不进行后面操作,告知调用方订单重复提交:

var cachekey=string.Format("___PaySettleAccount_{0}",model.OrderNO);
if(CacheUtils.Contains(cachekey))
return Json(OperationResult.ErrorResult("频繁并发请求限制!", -999));
CacheUtils.Set(cachekey, "true",1);
。。。。。。。
// 查询数据库是否存在该笔订单号,存在则不插入

B。加入常用的Lock方式
private static object Lock = new object();
[Httppost]
public static JsonResult Pay(PayOrder payOrder)
{
lock(Lock )
{
.......................
// 查询数据库是否存在该笔订单号,存在则不插入
}
}
A方法能否有效避免重复提交,B方法感觉很怪异,笨重。。。
...全文
579 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
datahandler2 2016-03-17
  • 打赏
  • 举报
回复
引用 10 楼 sp1234 的回复:
不管你在客户端人家的操作、电脑、键盘鼠标上做什么手脚,不管有没有那个闲工夫去编写代码,你总应该首先使用上数据库系统本身的唯一约束吧!
我们的唯一性主键不是根据客户订单号来创建的。不好再更改这个主键
newtee 2016-03-17
  • 打赏
  • 举报
回复
引用 7 楼 tiancaolin 的回复:
[quote=引用 2 楼 zhuankeshumo 的回复:] B 不行 根据订单号加锁
我咋感觉跟你相反,A不行,B可以呢?[/quote]B太慢了 锁的是所有的订单 A 如果是分布式部署 可以用redis的锁 单台的话 用本地缓存lock就行
  • 打赏
  • 举报
回复
不管你在客户端人家的操作、电脑、键盘鼠标上做什么手脚,不管有没有那个闲工夫去编写代码,你总应该首先使用上数据库系统本身的唯一约束吧!
datahandler2 2016-03-17
  • 打赏
  • 举报
回复
引用 4 楼 yi_iy 的回复:
可能主要是网络或者电脑卡,客户端点击一次没反应 又点击了第二次,发送了两次。 如果你点击一次直接弹出一个加载遮罩,基本上可以防止。 解决根本问题还是要还是B吧.
这个不是由页面点击按钮进行表单提交,是由调用方的后台线程作业提交。。
datahandler2 2016-03-17
  • 打赏
  • 举报
回复
引用 2 楼 zhuankeshumo 的回复:
B 不行 根据订单号加锁
我咋感觉跟你相反,A不行,B可以呢?
  • 打赏
  • 举报
回复
#8 楼,是回复这个
引用 5 楼 tiancaolin 的回复:
[quote=引用 3 楼 sp1234 的回复:] 难道订单号在你的系统中没有成为一个唯一约束吗?
订单号是调用方提供的,接收方也就是这个API系统不判断。。。。 调用方在从他们的订单表中通过作业提交的时候,有存在未知问题,出现并发同时调用我们系统的可能性。。讨论的重点就是防止这个问题。[/quote]
  • 打赏
  • 举报
回复
说的就是这个啊?! 难道你说调用方的订单号不是唯一约束的,然后你要“防止这个问题”,你又不认为订单号是具有唯一约束的?这是在转圈。
datahandler2 2016-03-17
  • 打赏
  • 举报
回复
引用 3 楼 sp1234 的回复:
难道订单号在你的系统中没有成为一个唯一约束吗?
订单号是调用方提供的,接收方也就是这个API系统不判断。。。。 调用方在从他们的订单表中通过作业提交的时候,有存在未知问题,出现并发同时调用我们系统的可能性。。讨论的重点就是防止这个问题。
  • 打赏
  • 举报
回复
难道订单号在你的系统中没有成为一个唯一约束吗?
  • 打赏
  • 举报
回复
可能主要是网络或者电脑卡,客户端点击一次没反应 又点击了第二次,发送了两次。 如果你点击一次直接弹出一个加载遮罩,基本上可以防止。 解决根本问题还是要还是B吧.
newtee 2016-03-17
  • 打赏
  • 举报
回复
B 不行 根据订单号加锁

62,047

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧