1. What is idempotency?
"Idempotency" means that the result (side effect) obtained by repeatedly performing an operation N times is equal to one execution.
For example: In the HTTP protocol, get request will get the same data
Second, why idempotency
's start with an example, let's say there is a remote withdrawals API interface
bool get_money(id, amount)
参数:
id:用户的账户
amount: 表示取多少钱
返回值:
true: 表示取钱成功
false: 表示取钱失败
情景一:
1、一位用户A 取100块钱, 这个请求,发送到了服务器
2、服务器正常的处理了这个请求,把用户A的总额,减去了100块钱, 这时,服务器把处理结果返回给客户端。
3、服务器把处理结果,返回给客户端,可是这时,由于网络不稳定, 导致客户端没有接受到服务器返回的处理结果,这时,用户(或者客户端)进行重试,同样的请求又到服务器,服务器又在用户A的总额中,减去了100块钱........
用户A 取了100块钱, 银行却扣了 200.................
The solution to this problem is: the
client is calling this interface, passing in a serial number,
bool get_money(id, amount, serial_number)
对于同一个操作(同一笔业务)流水号不变(在不同操作中,必须保证流水号的唯一性),
这时,如果服务器遇到上面那种情况,只需要判断客户端传过来的这个流水号,是否已经操作(处理)过了,如果已经处理过了,就直接把处理结果返回给客户端
这样,就不存在上面的问题了
3. Misunderstanding of the realization of idempotency on the server side
在服务端,一般情况下,对于每次请求,我们都会把 请求方、流水号、处理结果 存储在数据库中
如:
流水号 请求方 处理结果
20160311xxxx jiangxi0001 1
情景一:
1、客户端(请求方) jiangxi0002,过来一个请求,流水号是:20160311jiangxi0002xxxx
2、一般情况下,我们会先根据 ‘请求方’ 和 ‘流水号’ 取所在表查一下,看是否存在
3、假如,由于用户操作失误,服务端,同时接收到两个请求 A 和 B,请求A 和 请求 B的 ‘客户端(请求方)’ 和 ‘流水号’ 都相同。这时,两个请求同时处理,就可能碰到并发的问题了,导致这请求 A 和 请求 B 都向表中插了一条新的记录
解决方法:
在数据库中, 对 ‘请求方’ 和 ‘流水号’ 加唯一索引, 在请求来了之后,直接插入表,不进行查询操作,如果‘请求方’ 和 ‘流水号’已经存在,那么会插入失败, 这时我们再进行查询操作,确认是否已经存在,这样就能解决并发的问题了。