Flask和mysql多线程_Flask解析(二):Flask-Sqlalchemy与多线程、多进程

Sqlalchemyflask-sqlalchemy的session是线程安全的,但在多进程环境下,要确保派生子进程时,父进程不存在任何的数据库连接,可以通过调用db.get_engine(app=app).dispose()来手动销毁已经创建的engine,然后再派生子进程。最近线上的项目总是会报出数据库连接相关的错误,比如“Command out of Sync”,“Mysql server ...
摘要由CSDN通过智能技术生成

Sqlalchemy

flask-sqlalchemy的session是线程安全的,但在多进程环境下,要确保派生子进程时,父进程不存在任何的数据库连接,可以通过调用db.get_engine(app=app).dispose()来手动销毁已经创建的engine,然后再派生子进程。

最近线上的项目总是会报出数据库连接相关的错误,比如“Command out of Sync”,“Mysql server has gone away”,“Lost databse connection”,“Package sequence out of order”等等,最终解决下来,发现以上错误可以分为两种,一种是和连接丢失有关的,一种是和连接被多个线程(进程)同时使用了有关。

我们项目基于flask,有多线程的场景,也有多进程的场景。orm用的是flask的拓展flask-sqlalchemy。flask-sqlalchemy的使用必须基于flask的app实例,也就是说要在app上下文中才能使用flask-sqlalchemy,所以在某些离线(非web)场景下,我们也用到了原生的Sqlalchemy。

原生的Sqlalchemy的使用方式是

engine = create_engine(db_url)

Session = sessionmaker(bind=engine)

session = Session()

session.query(xxx)

首先要创建一个engine,engine顾名思义就是和数据库连接的引擎。在实际发起查询前,是不会创建任何connection的。创建engine时可以通过指定poolclass参数来指定engine使用的连接池。默认是QueuePool,也可以设置为NullPool(不使用连接池)。为了方便理解,可以把engine视为管理连接池的对象。

sqlalchemy中session和我们平时数据库里说的session是两个不同的概念,在平时数据库中,session的生命周期从连接上数据库开始,到断开和数据库的连接位置。但是sqlalchemy中的session更多的是一种管理连接的对象,它从连接池取出一个连接,使用连接,然后释放连接,而自身也跟随着销毁。sqlalchemy中的Connection对象是管理真正数据库连接的对象,真正的数据库连接在sqlalchemy中是DBAPI。

默认地,如果不传入poolclass,则使用QueuePool(具有一定数量的连接池),如果不指定pool_recycle参数,则默认数据库连接不会刷新。也就是说连接如果不适用,则一直不去刷新它。但是问题来了,在Mysql中,输入“show variables like "%timeout%"; ” ,可以看到有一个waittimeout,还有interacttimeout,默认值为28800(8小时),这两个值代表着,如果8个小时内某个数据库连接都不和mysql联系,那么就会断掉这个连接。所以,8个小时过去了,Mysql把连接断掉了,但是sqlalchemy客户端这边却还保持着这个连接。当某

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值