[100分赏格] PB开发的程序访问SQL2000频繁出现阻塞或死锁

[100分悬赏] PB开发的程序访问SQL2000频繁出现阻塞或死锁
首先谢过进来的高手!
问题如标题所示,先说一下我这里的环境:
PB开发的客户端,使用人数在50人左右,系统很复杂(主要是涉及的功能超级多,如果站在程序员的角度看,其实一点都不复杂),PB版本好像是6.5,不确定。
MS Sql2000做为数据库服务器,数据文件有4G左右,日志文件有3G。

现在的问题是,当客户端从SQL读取一些数据后,查看SQL server(执行sp_lock存储过程),会发现:
这个SPID会在被读取的数据表上,对某一个或几个PAG发出共享锁S
(我们知道,SELECT执行时,其实发出S锁是正常的。但不正常的是:我的客户端明明已经成功读取到了数据了,那么当前SPID为何还保持着S锁不释放?了解SQL server的人都知道,被加上S锁后,其它SPID要等到S锁解除后才能进行更新操作,如果S锁一直保持,那就形成了阻塞,如果永远这样,那就是死锁了。)

进一步研究,我又发现:我的客户端并不是读取所有数据都是这样的。同时,即使是读取同一个数据表,查询条件不同,S锁释放与否也不同。说得更明显一点,读取的数据很多时(比如超过1000条记录),就有可能出现锁定某个PAG不释放的情况。

我用SQL事件探查器追踪客户端执行的SQL语句,然后把相同的语句放到SQL查询分析器里去执行,我发现,无论读取多少数据都不会出现S锁一直保持的情况。那么,问题肯定出在客户端程序内部了。

对于上面的现象,我猜想,是不是客户端程序有一种数据缓冲或者延迟的功能?就好比,客户端向SQL申请读取1000条记录,但它只获取500条记录,其余500条记录它给它加S锁,等到需要要时候再去获取。对于PB,我不是很熟悉,所以无法确定我的理解是否正确,或者还有其它的原因?

另外,客户端源程序我无法看到,所以也无法进一步研究,但我想,如果我上述的猜想成立,那么应该可以设置那个缓冲记录的数量。那么在哪里设置呢?

以上问题,烦请进来的高人能够解答,或者能提供一些解决问题的思路。
无论如何,都谢谢了。
(这个问题,我之前另外有一帖,烦请参考:http://topic.csdn.net/u/20100331/16/b9754dc0-4aa7-48e6-8d21-bcdedb2e9555.html)
------解决方案--------------------
可以用pbkiller反编译你的pb做的exe程序,看看代码也许有帮助
------解决方案--------------------
莫非SQLCA.AutoCommit =true 

某程序段UPDATE没COMMIT,在等自动提交?

猜测而已,下班了,好运
------解决方案--------------------
我顶,这个还真不好找!!!
------解决方案--------------------
帮顶1,需要好好研究一下
------解决方案--------------------
sqlca.lock='rc'
------解决方案--------------------
如果 设了SQLCA.AutoCommit =false,执行任何sql语句后,包括datawindow 的相关执行 一定要commit 提交。马上释放掉事务。具体看一下数据库事务的概念,了解清楚sqlca.autocommit这个属性的原理。
  
------解决方案--------------------
http://topic.csdn.net/t/20040621/16/3110293.html  
http://topic.csdn.net/t/20040114/17/2664096.html
看来sql server 的问题可能大些。select 后边也加commit虽然没什么,不过那也要在程序里改啊,你现在程序都看不到也没什么办法。
------解决方案--------------------
http://www.medaili.info/browse.php?u=%20%20Oi8vd3d3LnN5YmFzZWJicy5jb20vc3liYXNlL3JlZGlyZWN0LnBocD90aWQ9Mjg5NCZnb3RvPWxhc3Rwb3N0&b=5


主要是这个:

SQL Server本身对锁处理的问题。说到这里要谈一下锁的“粒度”。SQL Server具有多粒度锁定,允许一个事务锁定不同类型的资源。为了使锁定的成本减至最少,SQL Server自动将资源锁定在适合任务的级别。锁定在较小的粒度(例如行)可以增加并发但需要较大的开销,因为如果锁定了许多行,则需要控制更多的锁。锁定在较大的粒度(例如表)就并发而言是相当昂贵的,因为锁定整个表限制了其它事务对表中任意部分进行访问,但要求的开销较低,因为需要维护的锁较少。按照粒度增加顺序依次为:RID(行标识符)、键、页、扩展盘区、表、DB。一般情况下,使用SQL语句读取数据时(或使用数据窗口的Retrieve方法提取数据),用到的是页级或行级锁。也就是说它读完一页就会释放再读下一页。但如果对一些数据量比较大的表,出现的锁比较多,SQL Server会自动升级为表级锁,对整个表进行锁定。这也没什么问题。关键是在有些情况下(目前不知道是哪个版本解决的),SQL Server会升级表锁而用完不释放!这就会产生问题,遇到这种情况,可考虑给SQL Server打SP4补丁,经试验打上Sp4后不再出现读取数据锁表问题。


前几年老用SQL SERVER,从没遇到过楼主的问题,不过也巧了,我用的都是SP4,不知帖子里讲的对不对。现在改ORALCE了。  楼主自己试试吧
------解决方案--------------------
以前也遇到类似问题,有空聊聊QQ:541446322,初步估计是PB事务控制或者DW取数方法问题
------解决方案--------------------
记住,更改数据后commit;
------解决方案--------------------
以前也遇到过,反复检查程序没发现有不妥之处,甚至执行简单的一条select * from view在遇到特殊数据时也会锁表,后来在微软官网上发现有锁的bug说明,打上补丁就再没出现过问题了,楼主的问题虽然可能是程序问题,但首先应该打补丁后再看。
------解决方案--------------------
搜了下以往的帖子。大致有:

1.数据窗口的Retrieveend事件的脚本中加COMMIT USING SQLCA 
http://topic.csdn.net/u/20081120/14/3d6322ba-8832-4eed-b755-a3d96e129468.html