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是那一个操作过来就是哪一个操作,只操作自己对数据的操作,从而保证了线程的安全
    在当下的阶段,必将由程序员来主导,甚至比以往更甚。
  • 相关阅读:
    (网页)中的简单的遮罩层
    (后端)shiro:Wildcard string cannot be null or empty. Make sure permission strings are properly formatted.
    (网页)jQuery的时间datetime控件在AngularJs中使用实例
    Maven Myeclipse 搭建项目
    MyBatis 环境搭建 (一)
    java 常用方法
    XML 基础
    JS BOM
    js 事件
    js 的使用原则
  • 原文地址:https://www.cnblogs.com/randysun/p/15518306.html
Copyright © 2011-2022 走看看