在连接慢速sql server 时容易出现 The connection does not support Multi 返回

复现条件:
1. 连接数据库的出口带宽必须很小, 我的测试数据库部署在阿里云上, 出口带宽只有1M; 如果是localhost则不能复现
2. SqlSugarClient必须在某个class的构造器中创建, 这个class 还必须是DI注入到controller里; 如果在调用方法里创建 SqlSugarClient, 则不会复现
3. 调用的方法必须是async / await 异步的
4. 环境:
win10 X64 专业版
visual studio 2017 15.9.18
asp.net core sdk 2.2.402
sqlserver 2012 express
5. 使用附件复现
a. 在远程数据库中执行
USE tempdb;
IF OBJECT_ID('tempdb.dbo.TestTable1') IS NOT NULL
BEGIN
DROP TABLE tempdb.dbo.TestTable1;
END
CREATE TABLE tempdb.dbo.TestTable1 (Name VARCHAR(50) NOT NULL);
INSERT TestTable1 (Name) VALUES ('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA'),('AAAA');
b. 修改 asp.net core 中的 MyClass.ConnectionString
c. 使用 JMeter 以每秒 20 req/sec 的频率访问, 访问频率越高, 越容易复现
MultipleActiveResultSetsError.zip
热忱回答(23)
-
VIP0
2020/4/29大哥,这个问题有解决方案了吗
0 回复 -
地狱人形师 VIP0
2020/6/17老兄,你是怎么解决的,我也是出现这种问题,头疼。
0 回复 -
朽木 VIP0
2021/4/26我一直在想是不是自己的使用方式不对,是不是依赖注入导致多个实体才这样的。
0 回复 -
fate stay night VIP0
2021/4/26@地狱人形师:这个问题就是 一个DB对象跨了多个线程 使用 并且用了异步方法出现的
0 回复 -
fate stay night VIP0
2021/4/26解决方案很简单:
1、开线程情况
开线程 {
var db=new sqlsugarclient(); //在线程里面new
}
2、找代码有没有单例 或者静态
0 回复 -
朽木 VIP0
2021/4/29@fate stay night:
奈何自己基础太差,抄了一些BlogCore的用法,我是单库,贴一下代码,麻烦大佬帮忙诊断。
我先是容器中注入:

仓储层建了一个UnitOfWork 用来处理事务

仓储中使用

服务层

不知道怎么改进才行
0 回复 -
fate stay night VIP0
2021/4/29@朽木:只要线程能够安全就没问题
0 回复 -
fate stay night VIP0
2021/4/29对了你这个demo的 sqlsugarcore要升级 太老了
0 回复 -
fate stay night VIP0
2021/4/29你的代码没问题 升级sqlsugarcore就好了
0 回复 -
朽木 VIP0
2021/4/30@fate stay night:我的是5.0.2.9版本。还是会报这个错误
0 回复 -
fate stay night VIP0
2021/4/30@朽木:都说了这个错线程安全引起的,不用怀疑
0 回复 -
fate stay night VIP0
2021/4/30我说的代DEMO没问题是跟楼主说的
0 回复 -
fate stay night VIP0
2021/4/30只要升级就行了
0 回复 -
朽木 VIP0
2021/4/30@fate stay night:没有怀疑ORM本身哈,是在思考我的用法是怎么出现线程问题的,也特意留意一下自己的版本会不会也是很旧。
在服务层中,每注入一个IBaseRepository<T>的时候,UnitOfWork都会被构建一次,不知道该怎么追踪线程问题
0 回复 -
fate stay night VIP0
2021/4/30@朽木:把代码改成最简单的API DEMO ,有问题把最简单的DEMO像楼主一样发出来
0 回复 -
朽木 VIP0
2021/4/300 回复 -
fate stay night VIP0
2021/5/1@朽木:DEMO可以重面吗?
0 回复 -
fate stay night VIP0
2021/5/1@朽木:你的例子没有任何意义 ,高并发都不会重现
0 回复 -
朽木 VIP0
2021/5/1@fate stay night:这个要上班再试试了。我的用法和demo一样的,就是公司sqlserver在美国,速度很慢,刷多几次就会出现。。
0 回复 -
fate stay night VIP0
2021/5/1@朽木:区别可大了,一行代码都可能引起错误,你给我DEMO至少要是可以重现的
0 回复 -
朽木 VIP0
2021/5/6@fate stay night:demo刷了很多遍,确实没能重现错误,我再看看什么问题吧,先请大佬喝杯奶茶。
0 回复 -
fate stay night VIP0
2021/5/6@朽木:所以说要针对出问题的代码进行处理 ,光发这个DEMO没有意义
0 回复 -
朽木 VIP0
2021/5/6@fate stay night:终于解决了,在项目里一点点排查,注释掉自定义中间件,日志过滤器等等一个一个试,最后发现注释掉权限过滤器刷了几十遍都不出来那个错误了,然后把自己的权限过滤器加到demo里面再试,无论如何也没重现,再回去看原项目的权限过滤器,发现其中一个异步方法漏写了await,难怪会出现线程问题。。
0 回复