幂等性&&数据库的锁

一.幂等性

幂等性是高等代数中的概念,这里不是讨论数学上幂等性的概念,而是讨论程序中幂等性。幂等性是系统的接口对外一种承诺(而不是实现), 承诺只要调用接口成功, 外部多次调用对系统的影响是一致的. 声明为幂等的接口会认为外部调用失败是常态, 并且失败之后必然会有重试.

比如系统A提供了接口f1给系统B调用,系统B调用了系统A提供的f1接口,发现超时,然后再调用一次,超时可能是由于系统A处理的有点慢导致,此时系统A会感知到接口f1的两次调用,如果f1是给用户的账户增加10000RMB的话,这样的场景可能会导致最终给用户增加了N*10000RMB(N>1),此时接口f1就需要做幂等性处理,不管这个请求重复调用多少次,最终只会给用户增加10000RMB,首先我们需要从业务层面去思考看能否解决这个问题,一般的业务都会根据业务逻辑推算出那些重复请求的,实在推算不出的话,我们就需要做额外的处理了,要求调用方调用f1的时候传递一个唯一性的请求标识进来,系统A感知到f1的调用后,会先查当前请求标识是否已经被接受,如果被接收的话,先看是处理中还是已经完成,如果是这两个状态中的任何一个,我们都认为是重复调用。要是查不到记当前请求被接受的记录的话,先插入一条当前请求被接受的记录,并且状态记录为处理中,然后再去处理请求,此时如果请求处理成功就把请求被接受的记录状态修改为处理成功,要是处理失败就把请求被接受的记录删除。如果处理成功就把当前请求被接受的记录状态修改为处理成功。

二.数据库锁

我们在写代码的时候经常会遇到这样的场景,从数据库中读取一批数据出来,然后根据一些逻辑条件修改这批数据,修改完后写回到数据库中,我们读出数据进行逻辑处理时,数据库中的这些数据可能已经发生变化了。为了保证上面数据的正确性,我们需要引入数据库的锁来解决这个问题即select for update锁,先对需要修改的记录加锁,等数据库事务提交后再把锁释放,这个过程中其他对数据的修改要先拿到这个锁才能继续做写操作。

1
SELECT * FROM XXXTable WHERE conditions FOR UPDATE