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参数。这样每个连接都会创建独立的内存数据库,测试运行之间完全隔离,不会互相影响。 - 保留共享缓存的场景:
- 测试开始前先检查表是否存在,不存在再执行创建语句(比如用
IF NOT EXISTS:CREATE TABLE IF NOT EXISTS MyTable (MyColumn int);); - 改用匿名临时内存数据库,连接字符串用
Data Source=:memory:,这样每个连接都是全新的独立内存库,完全隔离。
- 测试开始前先检查表是否存在,不存在再执行创建语句(比如用
内容的提问来源于stack exchange,提问作者Kurren
相关产品推荐
相关产品推荐

