requirements.txt
rurality/settings.py
utils/redis_cli.py
utils/onlyone.py
base/models.py
account/models.py
account/controllers/user.py
这里并发请求是指对于同一个资源同时进行多个增删改操作.
这种情况下我们需要保证所有请求是串行操作,防止数据异常.
这里主要是用到了redis lock功能.
base/models.py中基础model增加model_name和model_sign用来描述对应model属性.
其中model_name有base/controllers.py中统一报错会用到,同时如果以后增加统一日志会用到.
model_sign是这个model的唯一标识,我一般都设置成对应的表名,避免重复.
在account/models.py中的所有model都加上这两个属性.
utils/onlyone.py中可以看到具体的逻辑实现.
大概思路就是传入一个唯一的标识,代表一种资源,然后传入可以唯一表示其中一个资源对象的参数.
举例来说:
@onlyone.lock('something', 'name:sign', 'sign', 30)
@onlyone.lock('something', 'name', 'name', 30)
def create_something(name, sign, typ):
...
create(name, sign, typ)
我们现在要创建一个something,参数是name/sign/typ,我们在创建时需要判断name和sign都不能重复.
因此我们通过增加@onlyone.lock('something', 'name', 'name', 30)来保证相同name参数时,只有一个请求可以处理.
第一个参数something就是我们定义的这种资源的唯一标识.
第二个参数代表create_something方法传入的参数key值. 这个值帮助我们获取方法具体调用时,每个key对应的值.
第三个参数就是我们想要串行处理的标识,这里因为是name不能重复,所以这个标识就是name.
上面保证了涉及name的修改都串行处理了,但是sign还没有处理.
因此添加@onlyone.lock('something', 'name:sign', 'sign', 30).
这里第二个参数与上面的不同,原因是,现在要处理的是sign在create_something方法的参数中是排第二位.
所以我们需要知道sign前面的所有参数key,所以就要写name:sign,以冒号分隔.
最后一个参数30是超时时间,保证接口即使失败了,锁定的key也可以在30秒后过期。这个30一般与接口超时设置的时间相同.