TypeORM使用QueryRunner开启事务后未释放会造成什么后果?
TypeORM中手动创建QueryRunner但未释放资源的常见问题
- 数据库连接池直接耗尽
QueryRunner创建时会从连接池申请一个专属的数据库连接,和普通Repository操作自动申请、归还连接的逻辑不同,这个连接只会在手动调用runner.release()后才会回到连接池的可复用队列。如果未释放,哪怕事务已经提交/回滚完成,连接也会被一直占用。多次未释放的场景下,连接池的可用连接会被快速占满,后续所有数据库请求(包括普通查询、其他事务)都会因为拿不到连接阻塞、超时,最终导致整体服务不可用。 - 数据库侧连接异常触发
未释放的连接会长期以空闲状态挂在数据库服务端,通常数据库都会配置空闲连接回收策略,这类长期占有的无效连接一旦被数据库侧主动断开,就会让应用出现偶发的连接断开类错误,排查难度很高。 - 应用内存持续泄漏
QueryRunner实例内部维护了独立的事务上下文、查询缓存、事件监听绑定等状态资源,未释放的实例不会被GC自动回收,长期运行会导致应用内存占用持续上涨,极端情况下会触发内存溢出导致进程崩溃。
手动使用QueryRunner时,必须在所有逻辑执行完毕后(无论成功、失败、抛出异常)调用
release()方法释放资源,标准写法如下:
const connection = getConnection() const runner = connection.createQueryRunner() await runner.connect() await runner.startTransaction() try { const repository = connection.getRepository(PostgresUserEntity) const instance = repository.create({ username: 'john doe' }) await runner.manager.save(instance) // 其他业务操作... await runner.commitTransaction() } catch (e) { await runner.rollbackTransaction() } finally { // 无论执行结果如何都释放资源,归还连接池 await runner.release() }
内容的提问来源于stack exchange,提问作者Max Rogério
相关产品推荐
相关产品推荐

