fastapi后台任务中使用多线程调用数据库session报错

7 篇文章 0 订阅
5 篇文章 0 订阅
本文讲述了在处理批量耗时任务时,从串行API升级到并发多线程遇到的问题,包括子线程异常未被捕获、多线程共享会话导致的错误以及会话管理和事务处理的关键点。作者通过调整代码解决了这些问题,确保了并发环境下的稳定运行。
摘要由CSDN通过智能技术生成

起因

批量耗时任务创建的api,最开始采用for循环串行执行耗时任务,使用的是请求初始化时的数据库session,技术上没问题。

报错

但业务上需要优化成并发。

上来直接改造多线程,发现子线程很快stoped,根本没执行

坑1 子线程的异常不会被主进程捕获

望着代码陷入自我怀疑,再三确认了多线程的代码没问题,想起来如题的坑,于是在子线程的函数中加入try catch,通过logging主动捕获并打印出异常。

坑2 多线程使用同一个会话报错

异常打出来了:

Instance '<Target at 0x7efe1a66bb80>' is not persistent within this Session

于是修改子线程函数,增加参数,接受一个新创建的会话。继续报错如下:

坑3 旧会话需要关闭,新会话要添加数据实体

Object '<Target at 0x7ff45077d3f0>' is already attached to session '1' (this is '2')
from sqlalchemy.orm import sessionmaker
from your_model import YourModel, engine

## 关闭旧会话
session_old.close()


# 将实体添加到另一个会话中

# 创建会话
Session = sessionmaker(bind=engine)
session = Session()

# 创建一个新实体或获取现有实体
entity = YourModel(...)

# 将实体添加到会话
session.add(entity)

# 进行操作
# ...

# 提交会话
session.commit()

# 关闭会话
session.close()

终于,世界恢复平静!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>