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
相关产品推荐
相关产品推荐

