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

SQLite内存数据库跨进程测试异常:表已存在且无磁盘文件

SQLite内存数据库测试跨进程“留存”问题

测试代码

using System.Data.SQLite;

[Test]
public async Task InMemoryTest()
{
    using var connection = new SQLiteConnection(
        "Data Source=file:abc?mode=memory&cache=shared;"
    );
    await connection.OpenAsync();
    var command = connection.CreateCommand();
    command.CommandText = "CREATE TABLE MyTable (MyColumn int);";
    _ = await command.ExecuteNonQueryAsync();
    await connection.CloseAsync();
}

问题现象

该测试仅在内存数据库中创建一张表。首次运行测试时可正常通过,但在另一个进程中第二次运行时,会因提示“表已创建”而失败。奇怪的是,磁盘上并未找到任何持久化的数据库文件,为何内存数据库中的表会在测试运行之间“留存”?

补充说明: 使用以下连接字符串时也会出现相同问题:
Data Source=abc;mode=memory;cache=shared;

原因分析

这是cache=shared参数与命名内存数据库结合导致的:

  • SQLite的命名内存数据库(比如这里指定名称为abc),默认在同一进程内共享缓存;而cache=shared参数会将这个共享范围扩大到跨进程——只要创建该内存库的进程还在运行,其他进程通过相同名称+cache=shared就能访问到同一个内存数据库实例。
  • 测试框架在运行多次测试时,可能会复用测试进程,或者第二次启动的测试进程仍能连接到之前进程创建的共享内存库,导致表已存在的错误。
  • 没有磁盘文件是正常的,因为这确实是纯内存数据库,数据只存在于内存中,不会落地到磁盘。

解决办法

  • 最直接的解决: 去掉cache=shared参数。这样每个连接都会创建独立的内存数据库,测试运行之间完全隔离,不会互相影响。
  • 保留共享缓存的场景:
    1. 测试开始前先检查表是否存在,不存在再执行创建语句(比如用IF NOT EXISTS:CREATE TABLE IF NOT EXISTS MyTable (MyColumn int););
    2. 改用匿名临时内存数据库,连接字符串用Data Source=:memory:,这样每个连接都是全新的独立内存库,完全隔离。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 12:25:10