找回密码
 立即注册
首页 业界区 业界 .NET SqlSugar多线程下SqlSugarClient 的线程安全陷阱 ...

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

静轾 3 小时前
使用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="" ”
经定位,异常抛出位置在一个很普通的查询操作上:
  1. public List<SqliteDiskEntity> GetDisksByPDiskId(string env, string project, int pDiskId)
  2. {
  3.     return _db.Queryable<SqliteDiskEntity>().Where(x => x.PDiskId == pDiskId).ToList();
  4. }
复制代码
连接字符串没有问题,数据库文件也正常存在,且异常并非每次必现,而是偶发性的。
排查过程

1. 排除连接字符串问题 
连接配置如下,看起来没有明显问题:
  1. 1 private static SqlSugarClient CreateClient(string dbPath)
  2. 2 {
  3. 3     return new SqlSugarClient(new ConnectionConfig
  4. 4     {
  5. 5         ConnectionString = $"Data Source={dbPath};Version=3;Journal Mode=Wal;BusyTimeout=5000;",
  6. 6         DbType = SqlSugar.DbType.Sqlite,
  7. 7         IsAutoCloseConnection = true,
  8. 8     });
  9. 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)。
整个调用链路如下:
1.png

这个错误的迷惑性在于:

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

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

相关推荐

您需要登录后才可以回帖 登录 | 立即注册