讨论:如何安全的处理数据库发问题。问题非常棘手,希望对MS SQL并发处理有独到见解的高手参加!

bearbaba 2004-10-24 10:56:10
问题背景:最近在开发一个项目,由于该项目所设计的软件使用人在同一时刻会超过50人以上,也就是说会有同一时刻有50个人在对某一张表做插入操作。通过用暴力测试(测试内容:事物处理之插入操作,每台客户端各连续不停的添加20000条记录,共有20台机器参与测试。测试工具采用自己写的自动测试机),很不幸的发现,第一台机器会以独占方式工作,后面的机器可以获得请求,但是结果是MS SQL服务器假死机了。等到所有20台机器都完成了,服务器又活了。
测试代码基本结构:

测试语句例如 Insert into a(col1,col2)value(var1,var2);
for (int i=0; i < 20000;i++)
{
数据库连接请求
事物处理语句块
完成后,关闭数据库连接
}

不知道为什么程序会独占方式工作?
请教各位大侠,有没有什么好的办法处理并发问题呢?
如果我要实现求解这样一个问题怎么做好呢?桌上有一盆菜,当有人看见自己喜欢吃就把一盆菜拿走了。言下之意,表中有诺干条记录,当用户看见这条记录有用就把这条记录抢走了,后来的人就看不见了。我如何在程序中实现让广大用户能够比较实时的看见记录已经被别人抢走了而不是在自己发出抢劫的命令后,得到回复已经被抢走了。

谢谢!希望大家多多讨论,共同进步!
...全文
372 点赞 收藏 39
写回复
39 条回复
切换为时间正序
请发表友善的回复…
发表回复
哈哈007哈 2004-11-08
祝贺你决定了结果
回复
哈哈007哈 2004-11-08
祝贺你决定了结果
回复
bearbaba 2004-11-01
我已经最终决定采用WinForm and WebForm + Webservice + SQLServer的结构开发了。
回复
Andy__Huang 2004-10-29
我覺得這種要用存儲過程來處理好一點﹗
回复
hglai 2004-10-29
50个人就会有问题??
你的程序设计有问题
我500个人都没有问题呢
回复
linfengcyl 2004-10-29
我其实也有同感,应该不会有问题:)
回复
cnming 2004-10-29
你的服务器是什么配置?

你的服务器运行状况如何?

另外,for循环的循环速度很快,如果能满足你的一台机器的一个For循环,少说也可以满足100个以上的在线用户了

还有,你的测试代码是如何写的,也就是for循环里头的,是否有每次都从服务器上取回所有的数据的记录?如果有,请问你的数据记录有多少?

假使你真的要重新连接数据库和关闭数据库连接,你也没有必要再for循环体内打开和关闭。
数据库连接请求
for (int i=0; i < 20000;i++)
{
事物处理语句块
}
完成后,关闭数据库连接,因此针对单用户来说,不存在这么快速频繁地打开和关闭数据库连接


还有,我认为这个问题已经没有什么可以再探讨的了。
回复
bearbaba 2004-10-28
To LinFengCyl(林风):我这次测试的思路是这样的。
测试内容:用户连续执行20000次完整一次插入操作。看看是否有编码错误。同时测试所写的代码能否支持50人同时做插入操作的情况。
测试过程:有50台计算机(P4 2.4G 256MB)同时执行一个含有完整插入操作程序的循环,不断的向数据库添加数据。我个人认为:某个用户点击按钮一次完成插入操作,那么如果让机器自己做只要做一个循环就可以了。50个用户的插入操作就是由50台装有这种程序的机器自动执行。
测试问题:目前是20台上线测试,前5台机器还能构获得响应,但是只有第一台机器能够执行插入操作。我觉得这个问题可能出在我在一次插入操作完成后并没有停止,而是立刻产生第二次插入操作,所以别的机器只能请求服务器响应,但是服务器无能为力提供服务。

To Everyone: 希望大家加入一起讨论!我今天还会在做一个插入操作的版本。
回复
linfengcyl 2004-10-28
你仔细地讲讲你测试的软硬件环境/测试的过程以及代码的结构(伪代码就可以了).我是觉得你这种测试有问题.不用说操作数据库,你让50个循环2000次的东东跑一下都可以累晕机器的.
访问数据库我觉得这本书可以翻翻<<数据访问模式>>.
回复
siugwan 2004-10-27
gz
回复
lxrxyz 2004-10-27
我想说的是,客户的插入操作是不是和下面这个一样快?
for (int i=0; i < 20000;i++)
{
数据库连接请求
事物处理语句块
完成后,关闭数据库连接
}
且不说50个客户,5000个客户也达不到这种速度吧。
我认为你的测试方式有问题。
回复
哈哈007哈 2004-10-27
楼主的测试方法是吃力不讨好的方法
回复
bearbaba 2004-10-27
To z9945() :那个panel是我自绘的控件

To LinFengCyl(林风):原本我想测试的目的就是模拟同一时刻有50台以上的客户机同时想MS SQL发出数据处理请求,但是我现在碰到的问题是同时只有2台机器发出请求就会死机。我不清楚是我代码的问题还是MS SQL的问题。

To Everyone: 我找到微软的关于三层结构的代码,但是我没有看明白为什么加了一个中间层或者说是数据层,在数据处理的时候就可以不需要打开数据库连接的问题。还有谁有三层结构的应用程序代码,我手上的是.net PetShop的代码。
回复
linfengcyl 2004-10-27
To BearBaBa:
1.我提些不相干的建议只是希望你能有好的编码规范,因为习惯是平时养成的.你测试时也可以暂时注释掉不相关的代码,这样越有对比性,也越易找到问题所在(恕我多言:));
2.关于ExcuteDataReader()和ExcuteXmlReader()之类的是因为它们都不能以连接自动关闭方式执行,所以最容易出现交叉使用连接的情况,这样会引发错误.要在程序中保证一个连接在做完一件事前不做另一件事是很难的.简单示例:
//connection为已打开的连接
SqlDataReader reader=connection.ExcuteDataReader();
connection.ExcuteNonQuery();//在DataReader关闭前执行该方法将引起错误.
reader.Close();
所以我建议做一个数据访问层或干脆像O/R Mapping,将具体的数据库存取细节封装起来.
3.我也在想你这种测试究竟是不是合理,因为我没有软件测试经验,所以不敢妄下评论.你测出来的结果是20台机器一台一台执行,不会交叉,那是不是涉及到计算机之间的通信及操作系统及Sql Server的问题而不会是你这里的代码问题.
我也希望知道结果:)
回复
z9945 2004-10-26
问个不相干的问题:
--------------------------------------------------
Form1.panel1.DrawColor = 3;// 个性化状态栏--颜色
--------------------------------------------------
我这里怎么没有这个属性啊?
回复
哈哈007哈 2004-10-26
Form1.panel1.DrawColor = 3;// 个性化状态栏--颜色
Form1.panel1.Text = "Successfully!"; // 个性化状态栏--文字
this.Close();//??关闭窗口,那finally还执行吗?



finally肯定要执行的
回复
哈哈007哈 2004-10-26
建议
1,如果不是3层架够(即普通的c/s)如果使用连接后不关闭连接,这样对减轻server负担用处不大,同时对网络资源和客户端资源会有一定量的消耗!
2,采用三曾架够,单独开发客户端程序中存取数据等操作剔除了连接数据库等繁杂的工作,对于中间业务逻辑层来说,不会有这种暴力测试的处理过程:

for (int i=0; i < 20000;i++)
{
数据库连接请求
事物处理语句块
完成后,关闭数据库连接
}

存在,最多会这样:

数据库连接请求
事物处理开启
for (int i=0; i < 需要发送的sql语句列表,不一定会连续执行某一客户端要求改变的所有语句,可能插入别的客户端提交的sql语句;i++)
{
执行
}
提交事物
关闭数据库连接,可不关闭
回复
luaiping 2004-10-26
看了一下你的代码
Form1.panel1.DrawColor = 3;// 个性化状态栏--颜色
Form1.panel1.Text = "Successfully!"; // 个性化状态栏--文字
this.Close();//??关闭窗口,那finally还执行吗?
回复
ncowboy 2004-10-26
//其实没有必要每次连接数据库和关闭数据库,这样纯粹耗费SQL服务器资源

我是严重的同意啊.不过要知道使用了连接池以后,你‘关闭’了连接,实际上并没有断开。如果你从tcp/ip层面断开断开连接,却是是增加负担(对于你过阵子又要使用,又要去连接的情况)。

btw,‘顶’,‘学习’之类的词语就不要出现了嘛。如何?
回复
thantii 2004-10-26

高手来解决了我就学习了
回复
发动态
发帖子
C#
创建于2007-09-28

10.4w+

社区成员

.NET技术 C#
申请成为版主
社区公告

全世界最好的语言,没有之一.