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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 00:54:02