84669 orang belajar
152542 orang belajar
20005 orang belajar
5487 orang belajar
7821 orang belajar
359900 orang belajar
3350 orang belajar
180660 orang belajar
48569 orang belajar
18603 orang belajar
40936 orang belajar
1549 orang belajar
1183 orang belajar
32909 orang belajar
经常听人说在交易系统中,生成订单的时候要控制好两个:一个是幂等性的控制,一个是并发性的控制。我的理解是这样的,并发性的控制,可以从数据库层面上,利用锁表中行的操作,分布式锁的方式来实现并发性,那么幂等性呢?查了一些资料对于幂等性这个概念的理解,还是越看越模糊,有没有什么通俗的对于幂等性的解释呢?此外怎么在生成订单的系统中做好幂等性的控制呢?所以我的问题是:1、怎么通俗的理解幂等性 ?2、如何在项目中做到幂等性的控制,防止订单碎片的产生??
谢谢~~
欢迎选择我的课程,让我们一起见证您的进步~~
谢邀~其实你的理解的有错的~不知道你这些资料是在哪里看到的…实际上…解决并发问题…不单单是简单的数据库锁能解决的…是需要通过一系列缓存、分流、过滤等共同实现的~而等幂性只是一个约定~约定用户在同一操作中~生效的只有一个~例如用户狂点下单~实际中生效的只有一个…解决方法很简单~分2层…前端控制点一次就不能再点…后端做请求唯一标识~然后在缓存中保存~之后真正生效的只有一个~
感觉你这几次问的问题更像是教科书中讲的东西~实际应用中远远不是那样的~建议可以关注下科技累的一些文章~例如 淘宝写的秒杀原理~阿里云最近发表的 高并发下红包系统的架构等实际生产中总结的干货~
幂等性是系统的接口对外一种承诺(而不是实现), 承诺只要调用接口成功, 外部多次调用对系统的影响是一致的. 声明为幂等的接口会认为外部调用失败是常态, 并且失败之后必然会有重试.
至于你说的防止订单碎片,我所知道的就是依靠事务了,像支付宝那种高并发环境我也不清楚他们是用的什么。
用token啊,不仅仅能防止csrf,也能防UI层面的重放。
一个简单的例子对幂等性的理解
public class Main { private int i = 0; //这个方法不具有幂等性,每调用一次,它就会改变Main的状态(即改变了i) public void idempotent() { i++; } //幂等性,无论这个方法调用多少次,它都不会改变Main类的状态。 public void simple() { System.out.println(i); } }
我理解的打印订单需要幂等性,是打印订单时不能数据的状态,同一个订单无论打印多少次,不会影响到其它订单的打印。这个很好控制啊,打印订单的时候别修改数据库的数据,把数据取到应用端再做处理,就不会对数据库端造成碎片。
冥等性指的是对业务系统的调用,如果发生多次调用,对业务系统不会造成影响。这个需求是在做分布式系统中很重要,因为分布式系统中,靠数据库本身已经无法完成事务的控制,会采用一些消息队列、异步调用的方式,在碰到一些异常情况远程调用状态不明确的时候,会尝试重新做一次远程服务的调用,如果服务没有冥等性保证的话,就不能用重试的机制了。
对于创建订单的场景,本身不是冥等性的,如果调用多次就会出现多张订单。通常的处理办法是在创建订单前,根据传递过来的信息做查询,如果已经执行过,就直接返回调用成功的信息,防止出现重复订单。
幂等性你可以理解为HTTP里面的GET请求(不要说你访问同一网址有时候内容不一样哈),POST请求就是非幂等性的。所以呢大多数时候,使用GET还是不错的!也千万不要觉得POST好像把body数据隐藏了就安全哈。
幂等解决的是在分布式系统中如果出现了超时等网络原因,导致client不知道server到底是执行成功了还是失败了。这个时候需要client做重试。如果接口不是幂等。会造成预期不同的结果。
简单的说一个接口如果是幂等的,你调用一次和多次效果都是一样的。比如
UPDATE table SET NAME="LILEI" WHERE UID='1'
谢邀~其实你的理解的有错的~不知道你这些资料是在哪里看到的…
实际上…解决并发问题…不单单是简单的数据库锁能解决的…是需要通过一系列缓存、分流、过滤等共同实现的~
而等幂性只是一个约定~约定用户在同一操作中~生效的只有一个~例如用户狂点下单~实际中生效的只有一个…解决方法很简单~分2层…前端控制点一次就不能再点…后端做请求唯一标识~然后在缓存中保存~之后真正生效的只有一个~
感觉你这几次问的问题更像是教科书中讲的东西~实际应用中远远不是那样的~建议可以关注下科技累的一些文章~例如 淘宝写的秒杀原理~阿里云最近发表的 高并发下红包系统的架构等实际生产中总结的干货~
幂等性是系统的接口对外一种承诺(而不是实现), 承诺只要调用接口成功, 外部多次调用对系统的影响是一致的. 声明为幂等的接口会认为外部调用失败是常态, 并且失败之后必然会有重试.
至于你说的防止订单碎片,我所知道的就是依靠事务了,像支付宝那种高并发环境我也不清楚他们是用的什么。
用token啊,不仅仅能防止csrf,也能防UI层面的重放。
一个简单的例子对幂等性的理解
我理解的打印订单需要幂等性,是打印订单时不能数据的状态,同一个订单无论打印多少次,不会影响到其它订单的打印。这个很好控制啊,打印订单的时候别修改数据库的数据,把数据取到应用端再做处理,就不会对数据库端造成碎片。
冥等性指的是对业务系统的调用,如果发生多次调用,对业务系统不会造成影响。
这个需求是在做分布式系统中很重要,因为分布式系统中,靠数据库本身已经无法完成事务的控制,会采用一些消息队列、异步调用的方式,在碰到一些异常情况远程调用状态不明确的时候,会尝试重新做一次远程服务的调用,如果服务没有冥等性保证的话,就不能用重试的机制了。
对于创建订单的场景,本身不是冥等性的,如果调用多次就会出现多张订单。通常的处理办法是在创建订单前,根据传递过来的信息做查询,如果已经执行过,就直接返回调用成功的信息,防止出现重复订单。
幂等性你可以理解为HTTP里面的GET请求(不要说你访问同一网址有时候内容不一样哈),POST请求就是非幂等性的。所以呢大多数时候,使用GET还是不错的!也千万不要觉得POST好像把body数据隐藏了就安全哈。
幂等解决的是在分布式系统中如果出现了超时等网络原因,导致client不知道server到底是执行成功了还是失败了。这个时候需要client做重试。如果接口不是幂等。会造成预期不同的结果。
简单的说一个接口如果是幂等的,你调用一次和多次效果都是一样的。比如
UPDATE table SET NAME="LILEI" WHERE UID='1'