首页 新闻 会员 周边

用了14年的Dotnet,第一次遇到这样的问题!在多线程程序里用ado获取 dataset,数据乱窜

0
悬赏园豆:30 [已关闭问题] 关闭于 2016-10-21 14:15

 在公司软件产品中,用 ado 通过 存储过程 获取数据存放在 dataset中,我明明获取的是“订单数据”,但得到的却是“库存数据”(不是一直这样,偶尔发生这种情况,且有的客户端发生,有的客户端不发生)

客户端是多线程程序,且界面有不少后台线程在抓取不同的业务数据。(c#,sqlserver 2008,Framework 4.0)

 

有没有哪个大侠告知一下怎么解决啊,快疯了。。。

 

可以确认 DBHelper 全是静态方法 ,方法之间没有共享的属性。(就算手工用 SqlCommand写也会出现问题)

怀疑是数据库连接池问题?Ado.net缓存问题?Framework版本问题?

问题补充:

同样的代码,有的好,有的坏,所以排除数据库数据的问题。

硬件机器、操作系统都换过,所以排除硬件问题。

就剩下Framework环境和网络环境问题了。网络方面一直没有发现问题,现在只能从环境和自身代码角度找问题了。

 

dsPT = this.getPTPlan_Info(connectionString, trainNO, startTime, endTime, areaString);
                if (((dsPT == null) || (dsPT.Tables.Count == 0)) || (dsPT.Tables[0].Rows.Count == 0))
                {
return null;
                }
dsTD = this.getTDPlan_Info(connectionString, trainNO, startTime, endTime, string.Empty);

 

红色代码标记里面就是访问数据库存储过程了,类似:

 

SqlParameter[] commandParameters = new SqlParameter[] { new SqlParameter("@TRNO_DEPI", SqlDbType.VarChar, 20), new SqlParameter("@Time_START", SqlDbType.DateTime), new SqlParameter("@Time_END", SqlDbType.DateTime), new SqlParameter("@AREASTR", SqlDbType.VarChar, 0x1f40) };
            commandParameters[0].Value = trainNO;
            commandParameters[1].Value = startTime;
            commandParameters[2].Value = endTime;
            commandParameters[3].Value = areaString;
            return SqlHelper.ExecuteDataSet(connectionString, CommandType.StoredProcedure, "PR_getTDPlanInfoProcedureName", commandParameters);

 

得出的结果里面,不是上述业务数据的任何一种,而是其他方面的业务数据。SqlHelper.ExecuteDataSet的代码如下:

 

public static DataSet ExecuteDataSet(string connectionString, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)         {            

  DataSet set2 = null;

            using (SqlConnection conn = new SqlConnection(connectionString))             {                 SqlCommand cmd = new SqlCommand();                 conn.Open();

                try                 {                    

PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);

                    using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))

                    {                        

  DataSet dataSet = new DataSet();

                        adapter.Fill(dataSet, "ds");                         cmd.Parameters.Clear();

                        set2 = dataSet;                    

}

                }                 finally                

{                     cmd.Dispose();                     conn.Close();                 }             }            

return set2;         }

 

老早的系统,代码写的有点原始,没办法,只能在前人的基础上不停改进,呵呵。

 

此问题不是一直出现,一天在3个时段出现概率大,其他时段也出现,但没啥规律。

康康的主页 康康 | 初学一级 | 园豆:172
提问于:2016-09-29 03:00
< >
分享
所有回答(8)
0

可以debug看看那个dataset是不是有时也存放了库存数据。。很简单的思路!从DB到后台再到客户端三个方面按顺序debug查看下数据到哪出现了问题。。。

 

~扎克伯格 | 园豆:1923 (小虾三级) | 2016-09-29 09:02

每个DataSet都是在方法内临时创建的,用完就丢的,没有任何缓存

 

生产环境无法Debug,只能谢谢日志、监控工具什么的,测试环境没问题。

支持(0) 反对(0) 康康 | 园豆:172 (初学一级) | 2016-09-29 12:12
0

这些数据有缓存吗,有的话先不用缓存检测一段时间。

清海扬波 | 园豆:825 (小虾三级) | 2016-09-29 09:06
0

不是“数据库连接池问题”,也不是“Ado.net缓存问题”,更不是“Framework版本问题”,建议从其他角度下手

dudu | 园豆:31007 (高人七级) | 2016-09-29 10:01

同样的程序,在另外一台机器完全好使,就这一台老窜,而且不存在缓存,获取数据逻辑都在一个方法里,不涉及任何属性,就是DataSet里面的数据变成了另一个存储过程返回的数据了。除了环-境问题,我实在想不出还有什么可能。

 

在DotNet开发这么多年,第一次碰到这种问题。跟中奖似的。

支持(0) 反对(0) 康康 | 园豆:172 (初学一级) | 2016-09-29 12:06

@康康: 你一直想这样低成本解决问题的话,

我有一个好方法,

1、让客户把这台电脑扔了。

2、不行的话,你买一台给他。

这是最低成本的解决方法了。

支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2016-09-29 12:55

@爱编程的大叔: 机器换过了,我是从上海到乌鲁木齐,来回机票钱都够买的了,呵呵。

支持(0) 反对(0) 康康 | 园豆:172 (初学一级) | 2016-09-29 13:23

@康康: 嫌疑最大的依然是程序中的代码,只不过这台机器的某些环境触发了问题

支持(0) 反对(0) dudu | 园豆:31007 (高人七级) | 2016-09-29 13:51

@康康: 建议把 getTDPlan_Info() 改为静态方法试试

支持(0) 反对(0) dudu | 园豆:31007 (高人七级) | 2016-09-29 13:56
0

丢代码出来看看吧。如果ado.net在这块有问题那早就玩完了。

Daniel Cai | 园豆:10424 (专家六级) | 2016-09-29 10:03

之前我也这么认为,所以加了无数日志。知道我每次都把DataSet里的数据都序列化到文件里,然后在写工具查看,才确认数据窜了。

支持(0) 反对(0) 康康 | 园豆:172 (初学一级) | 2016-09-29 12:13

@康康: 连接串呢?

支持(0) 反对(0) Daniel Cai | 园豆:10424 (专家六级) | 2016-09-29 13:21

@Daniel Cai: 外面传入的,我记了日志,也对的。

Data Source=ip\\INST1;Initial Catalog=DB_H;uid=sa;pwd=xxx;

支持(0) 反对(0) 康康 | 园豆:172 (初学一级) | 2016-09-29 13:27
0

用了14年还这样的话,你们公司的考虑下如何找一个能胜任的,或者说高薪的。

最起码目前得花一笔大价钱找个高手,这样问能问出来就奇怪了。

爱编程的大叔 | 园豆:30839 (高人七级) | 2016-09-29 10:30

话不要乱说,啥意思嘛。

哥做过的中大型软件怎么也有10几个了,小的软件都记不得的了。

能不能提点有建设性的意见?

支持(0) 反对(0) 康康 | 园豆:172 (初学一级) | 2016-09-29 12:09

@康康: 我的意思不是贬低你啊,就是这东西你可能陷入误区了,然而这种问题

上下文相关性很厉害的,不看着代码,不进行测试跟踪,那就真的只有God能帮你了。

可以很明确的告诉你:

怀疑是数据库连接池问题?Ado.net缓存问题?Framework版本问题?

这些都不是,程序员的问题不要老是想找微软背锅。

支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2016-09-29 12:19

@爱编程的大叔: 代码已放出,确认问题的方法我也在前面写了(序列化,再检查)。

我一直呆在客户现场,10.1还不知道怎么过呢,所以我写的绝对是实际情况,当然结论是我的猜测。

如果没有办法,我只能在日志里记录线程ID什么的,再复杂点的只能用WinDbg了(不过用的不熟,怕难以找到问题)

 

另外,此问题不是一直出现,一天在几个时段出现概率大,其他时段也出现,但没啥规律。

我也不是找谁背黑锅,毕竟人家微软就算有问题,但我的客户也不会管的。

我就想问问是不是有什么补丁我没打的。

支持(0) 反对(0) 康康 | 园豆:172 (初学一级) | 2016-09-29 12:36

@康康: 为什么这个问题不一直出现,而是在几个时段出现的概率大,是不是因为那几个时段用的人多数据并发造成的问题

支持(1) 反对(0) 释霁 | 园豆:204 (菜鸟二级) | 2016-10-13 17:01
0

先说两个问题之外的:

1. 代码能高亮么?

2. 是不是应该加点分?

其次是问题,先从自身找问题,取巧的方法找不到原因,就笨办法分段一点点测试。我的几点看法:

1. 数据不一样较大概率是取数据的时候sql语句错乱,好好监控一下吧

2. 写个方法模拟测试关键点,

3. 分析一下这几个时段的数据

 

皓月空 | 园豆:723 (小虾三级) | 2016-09-29 13:52

以前不咋在这问问题。加分的事我研究下的。

这个问题我折腾5天四夜了。我们系统全天运行。

问题代码也拿出来放在测试程序跑过,没问题。所以郁闷哪

支持(0) 反对(0) 康康 | 园豆:172 (初学一级) | 2016-09-29 14:19

因为没啥sql语句,都是存储过程,实在想不出咋弄

支持(0) 反对(0) 康康 | 园豆:172 (初学一级) | 2016-09-29 14:20

@康康: 想办法重现吧,抓一下重现时的参数和返回的数据,听你描述出现概率也不小

找一下出现此问题此问题的时候进行过的操作

我们这种吃瓜群众也是蒙,看不出来啥

支持(0) 反对(0) 皓月空 | 园豆:723 (小虾三级) | 2016-09-29 16:05
0

看起来很奇怪的样子,如果LZ实在找不到原因,建议抛弃DataSet和DataTable。从datareader手写一个一个的映射。然后在观察一段时间。

我叫So | 园豆:186 (初学一级) | 2016-09-29 17:06
0

这个一看就是多线程那里出现了问题,多个客户端请求ID和服务器的响应ID 出现没有对应上的问题。

比如说 A客户端请求 订单数据 ID为5,B客户端请求 库存数据 ID为6。多线程那里肯定是 共享了一个全局变量,多线程修改的时候,导致服务器 本来要给B的数据给成A。

需要格局 | 园豆:2145 (老鸟四级) | 2016-09-30 09:49
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册