使用rocket_db_pools时,能否在Rocket路由处理器中请求多个数据库连接?
问题描述
我正在运行Rocket服务器,使用rocket_db_pools实现PostgreSQL数据库连接。我希望在一次API调用的上下文内对同一数据库执行多个查询,示例代码如下:
#[get("/fetch_data_by_ids?<data_ids>")] async fn fetch_data_by_ids(data_ids: Vec<&str>, mut db: Connection<DatabaseConnection>) -> Json<Vec<ProcessedDocument>> { let connection_one = db.clone(); let connection_two = db.clone(); let data_obj_one = do_a_database_process_one(connection_one).await; let data_obj_two = do_a_database_process_two(connection_two).await; }
请问是否可以在一个路由处理器中请求多个数据库连接?
回答
当然可以在单个路由处理器中使用多个数据库连接,但你当前代码里的clone()方式要注意:rocket_db_pools的Connection克隆出来的是同一底层连接的引用,并非真正的独立连接。如果你的两个数据库操作需要并行执行,这种方式会让查询串行运行,达不到并行的目的。
要实现真正的并行查询,有两种更合适的方案:
- 直接声明多个
Connection参数:在路由函数参数里直接添加多个Connection<DatabaseConnection>,Rocket会自动从连接池分配独立连接,示例:
#[get("/fetch_data_by_ids?<data_ids>")] async fn fetch_data_by_ids( data_ids: Vec<&str>, db1: Connection<DatabaseConnection>, db2: Connection<DatabaseConnection> ) -> Json<Vec<ProcessedDocument>> { let (data_obj_one, data_obj_two) = tokio::join!( do_a_database_process_one(db1), do_a_database_process_two(db2) ); // 后续处理逻辑 Json(vec![]) }
- 通过连接池动态获取连接:如果需要动态创建数量不固定的连接,可以注入
Pool<DatabaseConnection>,再调用pool.get().await获取独立连接,示例:
#[get("/fetch_data_by_ids?<data_ids>")] async fn fetch_data_by_ids( data_ids: Vec<&str>, pool: Pool<DatabaseConnection> ) -> Json<Vec<ProcessedDocument>> { let db1 = pool.get().await.unwrap(); let db2 = pool.get().await.unwrap(); let (data_obj_one, data_obj_two) = tokio::join!( do_a_database_process_one(db1), do_a_database_process_two(db2) ); // 后续处理逻辑 Json(vec![]) }
额外注意:
- 连接池的最大连接数是在Rocket配置中设定的,要确保池大小能支撑你需要的并发连接数。
- 无论用哪种方式,Rocket都会自动管理连接生命周期,用完后自动归还到连接池,无需手动释放。
内容的提问来源于stack exchange,提问作者Thomas Murphy
相关产品推荐
相关产品推荐

