flask之 scoped实现线程安全.py

1、用法

导入模块,将Session传入scoped_session即可

from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session
from models import Users
from threading import local
engine = create_engine("mysql+pymysql://root:lqz123?@127.0.0.1:3306/sqlalchemy01", 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'
)
"""
# session=Session() # 不是线程安全---》多线程并发情况下---》用的是同一个,就会出现混乱
#scoped_session类并没有继承Session,但是却又它的所有方法

# 以后在多线程,协程情况下,使用这个session,就没有并发安全的问题
# 原理是什么? 内部使用了threading包下local对象,   local.session  在不同线程下执行这个取值或赋值,使用的都是当前线程自己的

# 线程1   local.a=100  后续的操作中--->取local.a--->永远是当时这条线程中放进去的a ,也就是100
# 线程2   local.a=999   --->取local.a--->永远是当时这条线程中放进去的a ,也就是999

#local对象如何实现的线程安全呢? 内部维护了一个字典,字典的key是线程id号,value值是
# l=local()  #  {}
# # 线程1
# l.session=线程1的session  # {线程1的id号:{session:新session}}
#
# # 线程2
# l.session# {线程1的id号:{session:新session},线程2的id号:{session:线程2的session}}



# 本质就是,不同线程,使用自己线程的那个session
# scoped_session 不是Session类的对象,但是他有 Session类对象的所有方法----》通过装饰器,装进去的
session = scoped_session(Session)
# ############# 执行ORM操作 #############
obj1 = Users(name="lqz4",email='3533@qq.com')
session.add(obj1)

# 提交事务
session.commit()
# 关闭session
session.close()

  

posted @ 2025-01-15 18:08  凡人半睁眼  阅读(28)  评论(0)    收藏  举报