You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中安全全局使用SurrealDB连接的实现方案咨询

在Rust中安全复用SurrealDB连接的方案

方案1:使用lazy_static + Arc<Mutex<Surreal>>

通过lazy_static实现延迟初始化,配合Arc<Mutex>保证多线程下的安全访问,完全避免unsafe代码:

use lazy_static::lazy_static;
use std::sync::Arc;
use tokio::sync::Mutex; // 适配异步场景,需用tokio的Mutex
use surrealdb::Surreal;

lazy_static! {
    static ref DB: Arc<Mutex<Surreal>> = Arc::new(Mutex::new(Surreal::new("0.0.0.0:8080").await.unwrap()));
}

#[tokio::main]
async fn main() {
    // 获取连接并执行操作
    let mut db = DB.lock().await;
    db.get("user", "whynotdogie").await.unwrap();
    db.create::<User>("nothendev").await.unwrap();
}

说明:

  • lazy_static确保连接仅在首次使用时初始化一次
  • tokio::Mutex保证异步场景下同一时间只有一个任务操作连接
  • Arc允许连接在多个异步任务间安全共享

方案2:使用once_cell的Lazy类型(现代替代方案)

once_cell是官方维护的库,提供更简洁的延迟初始化方式:

use once_cell::sync::Lazy;
use std::sync::Arc;
use tokio::sync::Mutex;
use surrealdb::Surreal;

static DB: Lazy<Arc<Mutex<Surreal>>> = Lazy::new(|| {
    Arc::new(Mutex::new(tokio::runtime::Runtime::new().unwrap().block_on(async {
        Surreal::new("0.0.0.0:8080").await.unwrap()
    })))
});

#[tokio::main]
async fn main() {
    let mut db = DB.lock().await;
    db.get("user", "whynotdogie").await.unwrap();
    db.create::<User>("nothendev").await.unwrap();
}

说明:

  • Lazy同样保证初始化的原子性和唯一性
  • 因Lazy::new是同步闭包,用tokio::runtime的block_on完成异步连接初始化

方案3:将连接作为应用状态传递(无全局状态)

如果不想依赖全局状态,可将连接封装到应用状态中,在需要的地方传递:

use std::sync::Arc;
use tokio::sync::Mutex;
use surrealdb::Surreal;

struct AppState {
    db: Arc<Mutex<Surreal>>,
}

#[tokio::main]
async fn main() {
    let db = Arc::new(Mutex::new(Surreal::new("0.0.0.0:8080").await.unwrap()));
    let state = AppState { db };

    // 在异步任务中共享状态
    let state_clone = Arc::new(state);
    tokio::spawn(async move {
        let mut db = state_clone.db.lock().await;
        db.get("user", "whynotdogie").await.unwrap();
    }).await.unwrap();

    // 主线程中使用连接
    let mut db = state.db.lock().await;
    db.create::<User>("nothendev").await.unwrap();
}

说明:

  • 完全避免全局状态,通过Arc在任务间共享应用状态
  • 适合Axum、Actix Web等Web框架,符合框架的状态管理模式

注意事项

  • 必须使用tokio::sync::Mutex而非标准库的std::sync::Mutex,否则会阻塞异步任务
  • 实际项目中不要用unwrap处理错误,建议通过Result类型优雅处理连接初始化和操作失败的情况

内容的提问来源于stack exchange,提问作者WhyNotDogie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 04:45:14