设计:
交易A可以直接插入数据库
交易B需要先根据订单号去数据库查询下有没有这条数据,没有才执行插入
问题:
假如B交易有并发请求的时候(订单号相同)查的时候是没有数据但是查询完之后另一个并发请求插入了数据,然后这个查询的也插入了数据,那就会造成B交易在数据库有重复订单号的情况。
图示:
解决方案:问一下怎么解决这个问题。
10
题主本人有个小小的建议,为什么不考虑把订单号设计成 兼容负载的呢?
你这一步假如是单节点没问题, 假如B交易有并发请求的时候(订单号相同)查的时候是没有数据但是查询完之后另一个并发请求插入了数据 可以考虑 在查的时候 加一把公共资源锁 ,为了保证 全部负载的服务可以及时获取到相关锁信息。
5
5
5
把查询订单号和插入订单号这两个操作放在一个存储过程中,程序只需要调用这个存储过程即可。
各大关系性数据库均支持存储过程。
5
题主都已经知道是并发引起的数据重复,那你设计的C表也是会出现这个问题的。原因是你的操作都是SELECT –> INSERT,
只要并发操作存在,这个动作就会引起数据重复
题主可以参考 redis 分布式锁,想简单的话可以利用自旋锁的方式,实现本人业务逻辑,也可以根据本人的业务搭建锁服务,
10
你本人的方案可行:
没有,假如用C表的话本人是把C表有个订单号那一列设置唯一索引的,这样B交易插入这张表的时候是会报错的,而对于A交易是不去操作这张表的。
将插入C表的操作和插入C成功后的操作放在一个事务里就行了。可行理论应该是可行的,就是不知道在真实的交易系统中能否是这样做的,想知道能否有更好的解决方案,这个为了一个交易而多加一张表其实感觉不太合理。
看了你上面的需求,你其实要解决的问题应该是避免请求的重复提交吧?这个重复请求的处理看你在什么地方了。
解决方案1:发送请求时控制,即请求1和请求2是同一订单号A,假设请求的原始数据为订单A,订单A发了两个请求,即请求1和请求2,需要控制住假如订单A发了一次请求后,不允许再发请求2. 在订单A发请求时,加一个锁定的状态,只允许发一次请求。
解决方案2:假如请求不受你的控制或说这个请求是其他系统的事情,他们只负责发请求,你这边要控制的话,按照你的想法,加一张表来记录这个订单号,唯一性控制。这种方法本人个人觉得挺好的。假如你要通过写代码,锁的形式就变得复杂了。