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

SQLite数据库执行操作后锁定,导致文件上传失败问题排查

解决SQLite文件锁定导致Blob上传失败的问题

以下是几个针对性的解决方案,按优先级排序:

1. 禁用SQLite连接池

SQLite默认启用连接池,就算用using块释放了连接,连接池里的闲置连接可能还攥着数据库文件的锁。直接修改连接字符串,加上Pooling=false:

// 示例修改后的连接字符串
string connectionString = "Data Source=filesystem/database/MainDatabase.db;Pooling=false;";

2. 复制数据库到临时文件再上传

最直接绕过锁定的办法是先把数据库文件复制到临时文件,上传临时文件后再删掉它,完全避开对正在使用的数据库文件的操作:

try
{
    string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
    string relativePath = @"filesystem\database\MainDatabase.db";
    string fullPath = Path.Combine(baseDirectory, relativePath);
    // 生成唯一临时文件路径
    string tempDbPath = Path.Combine(Path.GetTempPath(), $"TempDB_{Guid.NewGuid()}.db");
    // 复制原数据库文件到临时文件
    File.Copy(fullPath, tempDbPath, overwrite: true);

    blobMan blob = new();
    await blob.UploadFileAsync(tempDbPath, "database");
    ((MapViewModel)DataContext).MyVariable = "user successfully added, check your email";
    
    // 上传完成后删除临时文件
    File.Delete(tempDbPath);
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

3. 显式管理数据库事务

虽然你的插入代码没显式用事务,但SQLite会自动为单条语句创建隐式事务。显式控制事务提交,能确保锁及时释放:

public async Task<string> InsertDataAsync(string tableName, params object[] values)
{
    try
    {
        string query = $"INSERT INTO {tableName} VALUES ({string.Join(", ", Enumerable.Range(0, values.Length).Select(i => $"@Value{i + 1}"))})";

        using (SqliteConnection connection = new SqliteConnection(connectionString))
        {
            await connection.OpenAsync();
            // 开启事务
            using (var transaction = await connection.BeginTransactionAsync())
            {
                using (SqliteCommand command = new SqliteCommand(query, connection, transaction))
                {
                    for (int i = 0; i < values.Length; i++)
                    {
                        command.Parameters.AddWithValue($"@Value{i + 1}", values[i]);
                    }

                    await command.ExecuteNonQueryAsync();
                }
                // 提交事务,确保锁释放
                await transaction.CommitAsync();
            }
        }

        return "ok";
    }
    catch (Exception ex)
    {
        Debug.WriteLine($"Error inserting data into database: {ex.Message}");
        return "error";
    }
}

4. 排查其他潜在的连接占用

检查代码中有没有其他地方打开了数据库连接却没释放,比如全局的连接实例、或者其他异步操作没等待完成。可以用Process Explorer这类工具,查看哪个进程/线程在占用数据库文件,定位问题源头。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 23:12:33