SqlAlchmy Session的线程安全问题
2016-07-09 11:08
260 查看
代码码到一半,突然想到,Session是否是线程安全的?于是上官方文档,答案是否!
那问题来了,怎么破?因为它会牵涉到多线程情况下,调用rollback导致的不可预期影响。
官网给了两个方案:
使用 Contextual/Thread-local Sessions
不用全局的,而是采用函数间传递的session变量
明显,第一种方式对现在代码的改动最小,扩展性也更好。因为使用的flask-sqlalchemy,于是参考在线文档 ,发现table的定义与flask-sqlalchemy quickstart的定义不一致。文档里面有一句有趣的话
a preconfigured scoped session called session
那是否意味着 flask-sqlalchemy 对 sqlachemy 封装之后,将session做了多线程支持的封装?看源码!
self.session = self.create_scoped_session(session_options)
从这个变量赋值来看,就是scoped_session,为以防万一,再跟进去看
把这个代码与sqlalchemy的官方scope_session例子对比
完全一致!
所以,db.session是线程安全的,并且对sqlalchemy做了非常好的封装,便捷性更上一层楼,放心用吧!
那问题来了,怎么破?因为它会牵涉到多线程情况下,调用rollback导致的不可预期影响。
官网给了两个方案:
使用 Contextual/Thread-local Sessions
不用全局的,而是采用函数间传递的session变量
明显,第一种方式对现在代码的改动最小,扩展性也更好。因为使用的flask-sqlalchemy,于是参考在线文档 ,发现table的定义与flask-sqlalchemy quickstart的定义不一致。文档里面有一句有趣的话
a preconfigured scoped session called session
那是否意味着 flask-sqlalchemy 对 sqlachemy 封装之后,将session做了多线程支持的封装?看源码!
class SQLAlchemy(object): def __init__(self, app=None, use_native_unicode=True, session_options=None, metadata=None): if session_options is None: session_options = {} session_options.setdefault('scopefunc', connection_stack.__ident_func__) self.use_native_unicode = use_native_unicode self.session = self.create_scoped_session(session_options) self.Model = self.make_declarative_base(metadata) self.Query = BaseQuery self._engine_lock = Lock() self.app = app _include_sqlalchemy(self) if app is not None: self.init_app(app)
self.session = self.create_scoped_session(session_options)
从这个变量赋值来看,就是scoped_session,为以防万一,再跟进去看
def create_scoped_session(self, options=None): """Helper factory method that creates a scoped session. It internally calls :meth:`create_session`. """ if options is None: options = {} scopefunc = options.pop('scopefunc', None) return orm.scoped_session(partial(self.create_session, options), scopefunc=scopefunc)
把这个代码与sqlalchemy的官方scope_session例子对比
from sqlalchemy.orm import scoped_session from sqlalchemy.orm import sessionmaker session_factory = sessionmaker(bind=some_engine) Session = scoped_session(session_factory)
完全一致!
所以,db.session是线程安全的,并且对sqlalchemy做了非常好的封装,便捷性更上一层楼,放心用吧!
相关文章推荐
- 如何彻底卸载oracle
- mysql的备份与恢复
- mysql: update字段中带select
- window平台安装MongoDB
- mysql用户管理
- [置顶] redis3.2 学习记录 springmvc +jredis +redis 整合
- 关系范式
- hiredis-vip库,集群,异步实例
- 线上一个mysql死锁问题
- 怎样将结构完全一样的两个表的内容合并到一个表中,SQL语句
- redis常用命令
- 连接数据库取值出现Before start of result set
- mysql子查询例子
- [置顶] php结合redis实现高并发下的抢购、秒杀功能
- PL/SQL Developer去掉启动时自动弹出的Logon弹出框方法
- 快速熟悉oracle新坏境
- PL/SQL Developer去掉启动时自动弹出的Logon弹出框方法
- 数据库范式
- 用java连接mongodb并执行$sum和$avg结合的聚合函数的实例。
- redis配置文件详解