紧急求教:网络数据库的多用户录入问题(200分)

  • 主题发起人 主题发起人 huangxiangyang
  • 开始时间 开始时间
H

huangxiangyang

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大虾:
本人正在做一应用程式,但无法多人同时录入数据(MSSQL),出现一个检测到死锁的错误,请问如何解决,谢谢 !
代码如下:

数据库为MSSQL6.5,用TTable构件打开数据库(CacheUpdate属性为真),保存语句为ApplyUpdate.

If Database.InTranscation =False then
begin
Database.StartTranscation;
TTable.Append;
Try
TTable.ApplyUpdate;
TTable.CommitUpdate;
Database.Commit;
Except
...
Database.Rollback;
end;
end;
 
table的Exclusive属性怎样?
 
Delphi的table控件做得不太好,
会造成死锁的错误.
建议你用Tquery控件.
 
多用户环境千万不要用Table,一定用Query.可以看看<a href="http://www.gislab.ecnu.edu.cn/delphibbs/DispQ.asp?LID=106876">已答</a>问题,对这种情况的讨论很多.
 
如果有多个事务同时在处理,并且访问的是同一个表,这些事务彼此之间是相互影响的,是由TransIsolation属性设置的事务隔离级别决定的。如果这个属性设为tiDirtyRead,允许读其他事务对数据库尚未提交的修改。未提交的修改随时有可能滚回,因此,这种情况下读出来的数据是不可靠的。
如果这个属性设为tiReadCommitted,允许读其他事务对数据库已经提交的修改。
如果这个属性设为tiRepeatableRead,不允许读其他事务对数据库的修改。不同的服务器支持不同的事务隔离级别,
如果TransIsolation属性设置的事务隔离级别不被服务器所支持,BDE将自动降低事务隔离级别。
 
Query+UpdateSQL
 
记录被锁定只有SQL Server和Sybase有这种情况,我现在
用interbase一点都没有。究其原因是sql server的页锁。
不过ttable还是少用,效率低。
 
页锁的解决方法我的经验是:
1 使用Tquery代替TTable,重写以上更新句子
2 Tquery的SQL句子语法中select......for browse,注意for browse的用法。
也许能缓你所急,试试!
 
既然你使用Sql Server为何不用存储进程?
告诉你个避免死锁的好方法,也是最通用的方法
begin tran
update TableXXXX set FieldXXX =FieldXXX
where 1=2
if ....//调用你的sql语句
....
commit tran
前面的update语句使现在的进程获得一个独占的表锁,可以保证
没有其它事物能修改任何数据行.

但这种方法会增加对表锁定的争用,为了避免死锁总要牺牲一点的
您可以权衡一下


 
这段时间一直用clientDataSet,感觉不错。这样试试
clientDataSet-Provider-Query,可以会比query+cachedupdates 好一些。
当然,做多用户应用,尽量少用table.
 
这种事情我遇到过,有一些解决的经验
1。避免使用TTable,改用TQuery,或者TStoredProc
2。用死的数据集方式,通过update进行修改
3。在select的时候加上 "with (NOLOCK)",否则select几乎一定会锁住
4。避免系统的锁定,自己维护一张表,处理锁定,在其他用户企图修改一个
数据的时候,可查询此表,然后反回不得更新,避免了系统的阻塞
 
多人接受答案了。
 

Similar threads

后退
顶部