SQLiteDataReader导致数据库连接保持打开无法释放问题咨询
根因定位
你代码中的ReadDBBlob方法里获取的SQLiteBlob对象实现了IDisposable接口,但没有主动释放,这个非托管资源会持续持有数据库的写入锁,哪怕外层的SQLiteDataReader、SQLiteCommand、SQLiteConnection都通过using释放了,未回收的Blob资源还是会导致数据库处于只读锁定状态,和你观测到的“可读取不可写入”的表现完全吻合。
修复方案
1. 修复Blob资源释放
修改ReadDBBlob方法,给SQLiteBlob加上using包裹,确保用完自动释放资源:
private static byte[] ReadDBBlob(SQLiteDataReader rdr, string col) { byte[] data = null; if (!rdr.IsDBNull(rdr.GetOrdinal(col))) { using (SQLiteBlob blob = rdr.GetBlob(rdr.GetOrdinal(col), true)) { data = new byte[blob.GetCount()]; blob.Read(data, blob.GetCount(), 0); } } return data; }
修复后所有数据库相关资源都会正常释放,锁定问题会直接解决。
2. 优化查询逻辑(可选但建议)
你当前的SQL语句是直接字符串拼接,存在SQL注入风险,改成参数化查询更安全:
// 原字符串拼接查询替换为参数化 string query = "SELECT * FROM InstallationRecords WHERE RecordID = @RecordID"; using (SQLiteCommand cmd = new SQLiteCommand(query, localDBConnection)) { cmd.Parameters.AddWithValue("@RecordID", recordID); // 后续执行逻辑不变 }
另外你查询的是单条匹配记录,把while (rdr.Read())改成if (rdr.Read())即可,不需要循环处理。
额外排查建议
如果修复后仍偶现锁定,可做以下验证:
- 如果不需要获取表结构元数据,去掉
ExecuteReader的CommandBehavior.KeyInfo参数,减少额外的锁开销 - 检查连接字符串是否开启了连接池,测试时可临时加
Pooling=false验证是否是连接池持有连接导致的问题
内容的提问来源于stack exchange,提问作者VariableSquid
相关产品推荐
相关产品推荐

