内容简介:你的关注意义重大!-更多文章-
点击上方 “ 方志朋 ”, 选择“置顶或者星标”
你的关注意义重大!
(以下故事纯属虚构,如有雷同纯属巧合!)
一月的深圳,一如既往的炎热!
某天,烟哥正一边喝着 芝芝芒芒
,一边愉快的装13!
突然,小刘满脸愁容的找到了我,对我说:"烟哥,自从我们的单体应用拆成微服务架构后,不知为啥,老是出现数据不一致的问题!已经都快被客户骂死了,人家客户明明只点了一次,我们这边却有了两条数据!"
其实烟哥在装13的时候,被人打扰,这是大忌!大忌!然而,看在小刘是个妹纸的份上,我就不计较了!没错,我就是这么没原则的人!其实我本来可以直接告诉人家怎么解决的,然而无耻的烟哥,为了多和妹纸说会话,决定多啰嗦一会!
只见烟哥嘴角嘿嘿一笑,问到:"你知道 为什么拆成微服务架构后,会出现数据不一致问题么? "
接下来的情形,无法用言语形容,各位看官请看下面这张图
烟哥解释到:"因为在传统应用中,调用接口,只有两种状态 成功 和 失败 。但是呢,在微服务的架构下,还有第三种情况,那就是 超时 !小刘啊,你们的服务,调用另一个服务,如果超时了,你们是怎么处理的呢?"
小刘说:"重试啊!调用超时了,重试一下呗!"
这时,烟哥的表情突然变成了这样
烟哥回答到:"对的!小刘真聪明!然而, 重试只是一种方法! 还有一种就是,调用方在超时后,去查询一次被调用方。如果能查到数据,就代表调用过了,不继续执行,如果查不到数据,走失败流程!因为你们在调用超时的情况下,进行重试调用,就给系统带来了不一致问题了!因此我们必须给调用接口提供 幂等性 保证,防止重复调用出现不一致的情形!"
这个时候,小刘表情变成了这样
"哦,小刘,你懂?来来来,说说 什么是接口幂等性? "
说时迟,那时快,只见小刘挥舞着她的小手,说道:“接口的幂等性实际上就是接口可重复调用,在调用方多次调用的情况下,接口最终得到的结果是一致的。”
这种时候,烟哥痛心疾首,
只见烟哥眉毛微微一皱,开始装13的解释道:“如果按这么解释,比如一个查询接口。假设 SQL 是下面的这样的
select * from table;
这个时候,有一个线程,一直往这个 table
插入数据,那你每次调用查询接口的返回值肯定不一样啊!你能说查询操作不是幂等性操作?
应该要这么理解, 幂等性强调的是外界通过接口对系统内部的影响, 外界怎么看系统和幂等性没有关系,只要一次或多次调用对某一个资源应该具有同样的副作用就行。注意了,是对资源造成的副作用必须是一样的,但是返回值允许不同! ”
说到这里,小刘一脸懵逼的看着我。。。
烟哥说道:“就用,增、删、改、查来举例一下吧!”
(1)查询操作
查询操作并不会产生或变更新的数据,因此查询是天然具备幂等性。
(2)删除操作
这里分为 物理删除 和 逻辑删除
-
物理删除:删除只会进行一次,无论执行几次
delete
操作,造成的效果是一样的!是幂等性操作 -
逻辑删除:这类删除,是用
update
修改字段而已,这种操作无论update
几次,造成的效果是一样的!是幂等性操作
(3)增加操作
这里要看这张表是否带唯一索引。
-
带唯一索引Insert:此时如果重复插入操作,是会插入失败的!该操作是幂等性操作
-
不带唯一索引Insert: 这种情况是非幂等性操作。
(4)修改操作
要看修改了啥
-
计算式Update:这类操作是指
UPDATE table SET number=number-1 WHERE id=1
,这类SQL的操作,是非幂等性操作! -
非计算式Update:这类操作是指
UPDATE table SET number=3 WHERE id=1
,这类SQL操作,这种修改是属于幂等性的操作!
小刘:"烟哥,你可以先说说网上说的什么 on DUPLICATE KEY UPDATE
是什么东西么,就像下面这个SQL这样!"
insert into table (goods_id,update_time) values(#{goodsId},now()) on DUPLICATE KEY UPDATE update_time=now()
烟哥:"好,你还记得我刚说的,在表有唯一索引的情况下,此时如果有重复插入操作,是会插入失败的么!"
小刘:"嗯嗯。记得!"
烟哥:"OK,这种插入失败,从严格意义上来说是分为两种情况的!"
第一种就是 报唯一键冲突异常 !例如常规的 INSERT INTO tablename(列名) VALUES(列值)
这样的语句!
第二种就是 不报异常 ,Mysql提供了三组这样防止重复插入的语句,必须要有唯一索引才能用的
-
insert ignore into
:若有导致unique key
冲突的记录,则该条记录不会被插入到数据库中. -
replace
:若插入时如发现unique key
已存在,则替换原记录,即先删除原记录,后insert
新记录。 -
on duplicate key update
:若插入时如果发现unique key
已存在,则执行update
更新操作
小刘:"可是这些语句毕竟是 Mysql 的方言,换了数据库就不能用了啊!通用性太差,而且还规定一定要有唯一索引才能用!麻烦!"
此时烟哥的反应是这样的
烟哥捋了捋自己的思绪,说道:"回到我们刚才的话题,现在只有 不带唯一索引Insert 和 计算式Update 会引起幂等性问题的,懂了嘛?"
小刘抹了抹自己的眼泪,像下面这样
烟哥淡然的解释道:"现在网上大多数文章推荐全局token的方案,就是这样的。生成一个全局性唯一的token,然后请求过来的时候,查一下token存在么,存在代表做过了,就丢弃。不存在,就执行正常业务流程,把token丢到某个存储介质里!"
小刘听了听,摇了摇头:"烟哥啊,这个方案乍听之下很完美!但是细想一下还是有一点不大好。你看啊,假设有1000个请求,重复请求一般不到10个。为了这不到10个请求的正确性,让剩下990个正常的请求都多一个查询流程,这似乎不大妥吧!"
烟哥突然惊呆了,此刻感觉如下
烟哥补充道:“嗯,是的,所以我个人还是主张在数据库的操作上解决这个问题!就插入操作来说,建议还是建一个唯一索引,来防止重复插入!”
小刘:"可是我们的数据量很小,就是不想建索引怎么办?"
烟哥说道:“那你的插入语句可以像下面这么修改
INSERT INTO table(field1, field2, fieldn) SELECT 'field1',
'field2', 'fieldn' FROM DUAL WHERE NOT EXISTS(SELECT field
FROM table WHERE field = ?)
采 用这种写法,就可以防止重复插入,而且不需要建立唯一索引!SQL可以判断field字段有值,则不insert。如果无值,则会执行insert操作!这种方法其实就是使用了mysql的一个临时表的方式,但是里面使用到了子查询,效率也会有一点点影响。但是很重要的一点,这种写法在oracle里也能跑的通,通用性之强,无与伦比。如果真的达到了影响性能那个级别了,估计数据量够大,可以用上索引了。这会数据量太小,先这么写吧!”
小刘:"那针对修改场景怎么办?"
烟哥说道:“也很简单,加一个版本字段就行!比如,原来的sql为
UPDATE table SET number=number-1 WHERE id=1
,你加一个版本号字段就好啦,变成
UPDATE table SET number=number-1,_version=_version+1
WHERE id=1 AND _version= last_version
唯一的缺点,就是执行前,需要去数据查一下当前版本是啥!当然啦,如果你的表有唯一索引,用的又是 mysql
,又能保证将来不换其他数据库。可以试试 mysql
的 on duplicate key update
语句,该操作插入时如果发现 unique key
已存在,则执行 update
更新操作”
烟哥补充道:"在数据库层面的改变是最方便的,所以我一直主张,改sql,改表结构来解决幂等性问题。不要引入一堆七七八八的东东,徒增系统复杂度。好啦,小刘快回去改sql吧!"
于是,小刘就愉快的回去的改sql了!!
各位看官一定发现了,本来改个SQL就能解决的问题,烟哥硬是扯了半个多小时!当然,最后的结局就是下面这样
-更多文章-
-关注我-
看完了,帮我点个“好看”鸭
点鸭点鸭
↓↓↓↓
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 用大白话彻底搞懂 HBase RowKey 详细设计
- 大白话彻底搞懂 HBase Rowkey 设计和实现
- 白话大数据:大数据与机器学习在产品设计中的应用
- 白话布隆过滤器
- 白话 KMP 算法
- 一文科普:白话HTTPS
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Pro CSS and HTML Design Patterns
Michael Bowers / Apress / April 23, 2007 / $44.99
Design patterns have been used with great success in software programming. They improve productivity, creativity, and efficiency in web design and development, and they reduce code bloat and complexit......一起来看看 《Pro CSS and HTML Design Patterns》 这本书的介绍吧!