zoukankan      html  css  js  c++  java
  • 基于scoped_session实现线程安全

    一、基于scoped_session实现线程安全

    from sqlalchemy.orm import sessionmaker
    from sqlalchemy import create_engine
    from sqlalchemy.orm import scoped_session
    from models import Users
    
    engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/db_flask", max_overflow=0, pool_size=5)
    Session = sessionmaker(bind=engine)
    
    """
    # 线程安全,基于本地线程实现每个线程用同一个session
    # 特殊的:scoped_session中有原来方法的Session中的一下方法:
    
    public_methods = (
        '__contains__', '__iter__', 'add', 'add_all', 'begin', 'begin_nested',
        'close', 'commit', 'connection', 'delete', 'execute', 'expire',
        'expire_all', 'expunge', 'expunge_all', 'flush', 'get_bind',
        'is_modified', 'bulk_save_objects', 'bulk_insert_mappings',
        'bulk_update_mappings',
        'merge', 'query', 'refresh', 'rollback',
        'scalar'
    )
    """
    #scoped_session类并没有继承Session,但是却又它的所有方法
    session = scoped_session(Session)
    # ############# 执行ORM操作 #############
    obj1 = Users(name="randy")
    session.add(obj1)
    
    # 提交事务
    session.commit()
    # 关闭session
    session.close()
    

    二、底层实现原理

    2.1 scoped_session进入类

    from sqlalchemy.orm import scoped_session
    session = scoped_session(Session)
    
    for meth in Session.public_methods:
        setattr(scoped_session, meth, instrument(meth))
        
    public_methods = (
            "__contains__",
            "__iter__",
            "add",
            "add_all",
            "begin",
            "begin_nested",
            "close",
            "commit",
            "connection",
            "delete",
            "execute",
            "expire",
            "expire_all",
            "expunge",
            "expunge_all",
            "flush",
            "get_bind",
            "is_modified",
            "bulk_save_objects",
            "bulk_insert_mappings",
            "bulk_update_mappings",
            "merge",
            "query",
            "refresh",
            "rollback",
            "scalar",
        )
    
    1. 首先进入点击scoped_session进入scoped_session类查看如下内容

      for meth in Session.public_methods:
          setattr(scoped_session, meth, instrument(meth))
      

      1577885203996

      为scoped_sesion类设置属性

    2. public_methods中内容:

      这是在Session类中的内容

      public_methods = (
              "__contains__",
              "__iter__",
              "add",
              "add_all",
              "begin",
              "begin_nested",
              "close",
              "commit",
              "connection",
              "delete",
              "execute",
              "expire",
              "expire_all",
              "expunge",
              "expunge_all",
              "flush",
              "get_bind",
              "is_modified",
              "bulk_save_objects",
              "bulk_insert_mappings",
              "bulk_update_mappings",
              "merge",
              "query",
              "refresh",
              "rollback",
              "scalar",
          )
      
    3. setattr(scoped_session, meth, instrument(meth))这句中的instrument是一个闭包函数

      改闭包函数中实现了对数据库中具体操作

      1577885753015

    4. self.registry()中实现如下,为其实现了一个线程

      class scoped_session(object):
        
          session_factory = None 
      
          def __init__(self, session_factory, scopefunc=None):
            
              self.session_factory = session_factory
      
              if scopefunc:
                  self.registry = ScopedRegistry(session_factory, scopefunc)
              else:
                  self.registry = ThreadLocalRegistry(session_factory)
      
      

      线程内容如下,最终利用线程中的local()模块中实现线程的安全,也就是操作数据的安全:

      class ThreadLocalRegistry(ScopedRegistry):
      
      
          def __init__(self, createfunc):
              self.createfunc = createfunc
              self.registry = threading.local()
      

    总结:

    • session = scoped_session(Session)这个session是那一个操作过来就是哪一个操作,只操作自己对数据的操作,从而保证了线程的安全
    在当下的阶段,必将由程序员来主导,甚至比以往更甚。
  • 相关阅读:
    Linux面试题大全
    数据库学习002
    数据学习001
    003
    002
    001
    金蝶清空日志数据库脚本
    表格批量导入金蝶专业版销售订单
    金蝶单据清空记账标志
    金蝶单据字段审核后可修改
  • 原文地址:https://www.cnblogs.com/randysun/p/15518306.html
Copyright © 2011-2022 走看看