前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >谈谈幂等技术(二)

谈谈幂等技术(二)

作者头像
加多
发布2020-04-16 19:14:42
6340
发布2020-04-16 19:14:42
举报
文章被收录于专栏:Java编程技术Java编程技术

一、前言

前面我们讨论了《如何基于幂等表实现幂等处理》,本文我们就来看看如何基于乐观锁、悲观锁来做幂等处理。

二、基于数据库乐观锁进行幂等处理

首先我们看如何采用数据库的行锁+乐观锁来实现幂等。

在mysql Innodb存储引擎里面实现了行锁功能,当我们根据id去更新记录时就会获取到行锁。多个线程根据同一个记录id去更新行记录时只有一个线程可以获取到锁,其他线程会阻塞。

乐观锁的实现方式常见有两种:

  • 在业务表里面添加一个version版本字段
  • 使用业务表里面自带的状态机字段 比如订单流程,每个订单状态有:创建->支付->发货->验货等等。但是需要注意状态机不能出现回路,因为这会导致ABA问题。

上面两种方式本质一样,不同在于如果业务表里面自带的状态机字段,那么我们就不必额外加一个version字段了。下面我们统一称version和状态字段为幂等字段。

基于乐观锁实现幂等流程:

  • 根据select ... from biz_table where id = #id and 幂等字段=幂等字段值拿到DO对象
  • 根据DO对象进行处理:可能是修改DO对象里面的某些值
  • 进行乐观锁幂等:update biz_table set 幂等字段=新幂等值... where id = #id and 幂等字段= #DO对象.幂等字段;

如果使用version作为幂等处理字段,则上面第三步可以修改为: update biz_table set version=version+1... where id = #id and version= #DO对象.version;

如果使用业务状态作为幂等处理字段,则上面第三步可以修改为: update biz_table set 状态字段=状态机的下一个状态... where id = #id and 状态字段= #DO对象.状态字段;

可知基于乐观锁时,我们基于第三步做幂等处理。当多个相同id的请求同时(并发)或者先后(顺序)过来后,第一和第二步可能是并发或者顺序执行,但是第三步只有一个请求会返回1,其他都返回0,这就实现了幂等处理.

需要注意的是乐观锁方式在下面这种场景才用(以基于版本方案实现乐观锁为例):

image.png

也就是服务B内可以实现幂等处理前提是,调用方A把记录行id和行记录对应的版本号以参数形式传递过来了。

如下时序图中,服务A调用服务B时候如果只是把记录id传递给服务B,则当服务A顺序多次以相同记录id调用服务B时候,服务B是实现不了幂等的(因为多次调用时步骤2,3,4都会被执行)。

image.png

三、基于数据库悲观锁进行幂等处理

恕我直言,基于悲观锁实现不了通用的幂等处理,为何那?且让我们一一道来。

我们且来回忆一下幂等技术用来保证唯一性,就是相同参数的多次请求和一次请求对业务效果都一样。

而悲观锁处理流程一般为:

  • 开启事务
  • select ...from biz_table where id = #id for update 对行记录加锁,并返回DO对象
  • 对DO对象进行处理
  • update biz_table set ... where id = #id
  • 提交或者回滚事务

那么当多个id一样的请求顺序或者并行过来后,会导致上面五个步骤都执行(虽然并发过来时候,可能多个请求会暂时hold到步骤2),如果步骤三本身不是幂等的,那么这就起不到幂等作用了。

四、总结

这里我们补充下,幂等技术不是简单的对N多相同请求参数的请求,只处理其中一个,其他的请求忽略,直接返回。而是要保证即使这N多请求都处理了,但是处理的结果的效果和一次处理结果一样,所谓处理结果是指对业务的影响。

本节讲解的乐观锁方式相比基于幂等表方式,对业务入侵比较大,需要在业务表添加一个版本字段或者强依赖业务状态字段。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
  • 二、基于数据库乐观锁进行幂等处理
  • 三、基于数据库悲观锁进行幂等处理
  • 四、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档