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

如何在多个连接之间共享SQLite内存数据库

问题根因

你当前的错误是由连接配置和路径格式错误导致的,所有打开的连接实际创建了独立的私有内存数据库,自然无法互相访问数据。

必须修改的核心点

  • 必须使用完整的URI格式的数据库路径:file:zmem?mode=memory&cache=shared,不能仅使用zmem作为连接名
  • 打开连接时需要添加SQLITE_OPEN_URI flag启用URI解析功能,或者全局调用sqlite3_config(SQLITE_CONFIG_URI, 1)开启全局URI支持
  • 删除打开flag中的SQLITE_OPEN_MEMORY,该参数会强制每个连接创建独立的私有匿名内存库,和共享内存数据库的需求冲突
  • 多线程场景下如果没有自行实现并发访问控制,建议将SQLITE_OPEN_NOMUTEX替换为SQLITE_OPEN_FULLMUTEX,避免线程安全问题

修改后可运行的完整代码

#include <sqlite3.h>
#include <stdio.h>

int exec(sqlite3 *db, char* sql) {
    sqlite3_stmt *stmt;
    int ret;
    do {
        ret = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
        if (ret != SQLITE_OK) {
            printf("prep error: %s", sqlite3_errmsg(db));
            break;
        }
        ret = sqlite3_step(stmt);
        if (ret != SQLITE_DONE) {
            printf("step error: %s", sqlite3_errmsg(db));
            break;
        }
        ret = SQLITE_OK;
    } while(0);
    sqlite3_finalize(stmt);
    return ret;
}

sqlite3* getCon(char *name) {
    sqlite3 *db = 0;
    // 修改flags:去掉SQLITE_OPEN_MEMORY,添加SQLITE_OPEN_URI
    int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
            SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_SHAREDCACHE | SQLITE_OPEN_URI;
    int ret = sqlite3_open_v2(name, &db, flags, 0);
    if (ret != SQLITE_OK) {
        printf("open error: %s", sqlite3_errmsg(db));
    }
    return db;
}

void query(sqlite3 *db) {
    sqlite3_stmt *stmt = 0;
    do {
        int ret = sqlite3_prepare_v2(db, "SELECT * FROM MyTable", -1, &stmt, 0);
        if (ret != SQLITE_OK) {
            printf("prep error: %s\n", sqlite3_errmsg(db));
            break;
        }
        while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
            char *name = (char *) sqlite3_column_text(stmt, 0);
            printf("%s\n", name);
        }
        if (ret != SQLITE_DONE) {
            printf("step error: %s\n", sqlite3_errmsg(db));
        }
    } while(0);
    sqlite3_finalize(stmt);
}

int main() {
    sqlite3 *db = 0, *db2 = 0;
    // 修改为完整的URI格式路径
    char *label = "file:zmem?mode=memory&cache=shared";
    char bf[64];
    char *buf = &bf[0];
    int ret, i;
    do {
        db = getCon(label);
        if (!db) break;
        printf("connected\n");
        ret = exec(db, "CREATE TABLE MyTable (test VARCHAR(255));");
        if (ret != SQLITE_OK) break;

        for (i = 1; i <= 3; i++) {
            sprintf(buf,"insert into MyTable (test) values('Hello Row %d')", i);
            ret = exec(db, buf);
            if (ret != SQLITE_OK) break;
        }
        query(db);

        db2 = getCon(label);
        if (!db2) break;

        printf("connected 2\n");
        query(db2);
    } while(0);

    if (db) sqlite3_close(db);
    if (db2) sqlite3_close(db2);
    return 0;
}

运行效果

修改后输出如下:

connected
Hello Row 1
Hello Row 2
Hello Row 3
connected 2
Hello Row 1
Hello Row 2
Hello Row 3

注意事项

  • 该功能需要SQLite版本 >= 3.7.13
  • 所有指向该共享内存库的连接全部关闭后,数据库内容会自动释放
  • 多线程并发访问时需要遵循SQLite的线程安全规则,使用FULLMUTEX模式时SQLite会自动处理锁逻辑,不需要额外加锁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 09:09:03