静轾 发表于 2026-3-5 18:20:02

.NET SqlSugar多线程下SqlSugarClient 的线程安全陷阱

使用SqlSugar读取Sqlite数据库,项目运行过程中间歇性抛出以下异常:
SqlSugar.SqlSugarException:“中文提示 : 连接数据库过程中发生错误,检查服务器是否正常连接字符串是否正确,错误信息:Connection was closed, statement was terminatedDbType="Sqlite";ConfigId="".
English Message : Connection open error . Connection was closed, statement was terminatedDbType="Sqlite";ConfigId="" ”
经定位,异常抛出位置在一个很普通的查询操作上:
public List<SqliteDiskEntity> GetDisksByPDiskId(string env, string project, int pDiskId)
{
    return _db.Queryable<SqliteDiskEntity>().Where(x => x.PDiskId == pDiskId).ToList();
}连接字符串没有问题,数据库文件也正常存在,且异常并非每次必现,而是偶发性的。
排查过程

1. 排除连接字符串问题 
连接配置如下,看起来没有明显问题:
1 private static SqlSugarClient CreateClient(string dbPath)
2 {
3   return new SqlSugarClient(new ConnectionConfig
4   {
5         ConnectionString = $"Data Source={dbPath};Version=3;Journal Mode=Wal;BusyTimeout=5000;",
6         DbType = SqlSugar.DbType.Sqlite,
7         IsAutoCloseConnection = true,
8   });
9 }已开启 WAL 模式、设置了 BusyTimeout、配置了 IsAutoCloseConnection = true,表面上不应该出问题。
2. 调试器线程分析 —— 发现并发访问
在 Visual Studio 中暂停调试,查看线程窗口时发现了关键线索:
线程 ID 当前位置
34996        DiskSubscribeTimer_Triggered(object, SubscribeTaskArgs)
30716        ExecuteSubscribeTask(SubscribeTaskArgs) → RunSubscribeTaskAsync()
38276        DiskSubscribeTimer_Triggered(object, SubscribeTaskArgs)
虽然代码中用 ConcurrentDictionary 防止了同一个磁盘的并发执行,但不同的订阅任务仍然会并行运行,共享同一个 _db 实例。
问题根因及解决

_db是SqlSugarClient实例,所以,
此实例不是线程安全的。 当多个线程同时通过同一个 SqlSugarClient 实例操作数据库时,内部的连接/命令对象会发生竞争,导致 SQLite 底层返回 SQLITE_MISUSE(即 bad parameter or other API misuse)。
整个调用链路如下:

这个错误的迷惑性在于:

[*]连接字符串完全正确
[*]IsAutoCloseConnection = true 看似已经处理了连接释放
[*]异常只在多任务并发时偶发出现
[*]异常信息指向"连接错误",容易误导排查方向
将SqlSugarClient(非线程安全)改为SqlSugarScope(线程安全),即可
SqlSugarClient vs SqlSugarScope的区别,列个对比

 
出处:http://www.cnblogs.com/kybs0/让学习成为习惯,假设明天就有重大机遇等着你,你准备好了么本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

钨哄魁 发表于 2026-3-7 13:02:01

过来提前占个楼

边书仪 发表于 2026-3-12 04:22:15

懂技术并乐意极积无私分享的人越来越少。珍惜

孙淼淼 发表于 2026-3-12 04:28:53

yyds。多谢分享
页: [1]
查看完整版本: .NET SqlSugar多线程下SqlSugarClient 的线程安全陷阱