redisのsetnxを使用してリソースの原子的操作を保証する


マルチプロセス(スレッド)が共有リソースにアクセスすると、他のすべてのプロセス(スレッド)が同じ時間内に同じリソースにアクセスしないことを保証できます.原子操作(atomic operation)はsynchronizedを必要としない.これはマルチスレッドプログラミングの常識である.原子操作とは、スレッドスケジューリングメカニズムによって中断されない操作を指す.この操作はいったん開始されると、終了まで実行され、その間にcontext switch(別のスレッドに切り替える)はありません.
最新ではこの業務ニーズがあるので、同じviewで同じリソースを操作する権限があるのは1人だけであることを保証する装飾器を書きました.talk is cheap, show you the code:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Created by guozhihua12
#    view    ,     view       
import functools
from redis import RedisCache

redis_cache = RedisCache()


def view_lock():
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            #            id
            key = 'view_name_{}_id_{}'.format(getattr(func, '__name__'), args[0])
            #      
            result = redis_cache.setnx(key, '1')
            if result:
                try:
                    data = func(*args, **kwargs)
                except:
                    raise
                finally:
                    #    
                    redis_cache.delete(key)
                return data
            # todo                   
            raise Exception(message='         ,    !')

        return wrapper

    return decorator


@view_lock()
def test(id):
    print(id)


if __name__ == '__main__':
    test(12345)

コードの論理は比較的簡単で、python装飾器の原理を知っている学生さえいれば、理解するのは難しくありません.原理を言えば、redisのsetnxの属性を使用し、setnxが1を返すと、ロックの取得に成功したことを示し、対応するview操作を行うことができる.逆に、0を返します.このリソースは編集中で使用できないことを示します.操作が完了したら、異常がないかにかかわらず、ロックを解除します.