因事务中使用多个query操作出现程序阻塞(估计和MSSQL的锁有关)——困扰好几天了,HELP(200分)

  • 主题发起人 主题发起人 Geminiyc
  • 开始时间 开始时间
G

Geminiyc

Unregistered / Unconfirmed
GUEST, unregistred user!
数据库为MS SQL Server 2000,代码如下——<br>dm.localdb.StartTransaction;<br>&nbsp; try<br>&nbsp; &nbsp; &nbsp; dm.query1.close;<br>&nbsp; &nbsp; &nbsp; dm.query1.sql.Text :='insert into x_kh (jgh,khdm) values(''1000'',''12345678'')';<br>&nbsp; &nbsp; &nbsp; dm.query1.execsql;<br><br>&nbsp; &nbsp; &nbsp; dm.Query2.close;<br>&nbsp; &nbsp; &nbsp; dm.Query2.sql.text:='select * from k_zhk';<br>&nbsp; &nbsp; &nbsp; dm.Query2.open;<br><br>&nbsp; &nbsp; &nbsp; dm.Query3.close;<br>&nbsp; &nbsp; &nbsp; dm.query3.sql.text:='select * from x_kh'; &nbsp; <br>&nbsp; &nbsp; &nbsp; dm.Query3.Open; &nbsp; //执行到此时,程序阻塞<br><br>&nbsp; &nbsp; &nbsp; ....(省略)<br>&nbsp; &nbsp; except<br>&nbsp; &nbsp; &nbsp; dm.localdb.Rollback;<br>&nbsp; &nbsp; end;<br><br>这段代码中3句sql用了2个Query,若改为用3个Query分别执行问题依旧,只有始终使用同一个Query才不会发生异常。若去掉事务直接执行也不会发生异常,但这样都不满足我的需要了。<br>//注意,第一个sql和第三个sql都是对同一个表执行,当它们不是对同一个表执行时也不会发生异常。
 
这个问题前面讨论了一次,我以为可以勉强绕过去,结果还是不行。<br>http://www.delphibbs.com/delphibbs/dispq.asp?LID=3904154
 
这是程序发生阻塞时,使用sql server企业管理器的管理--当前活动--锁/进程ID查看到的消息:<br>正在阻塞——<br>对象 锁类型 模式 状态 所有者 索引 资源<br>ibank PAG IX GRANT Xact X_KH 1:125 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>ibank DB S GRANT Sess X_KH &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>ibank.dbo.K_ZHK PAG IS GRANT Xact X_KH 1:448 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>ibank.dbo.K_ZHK TAB IS GRANT Xact X_KH &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>ibank.dbo.X_KH RID X GRANT Xact X_KH 1:125:6 &nbsp; &nbsp; &nbsp; &nbsp; <br>ibank.dbo.X_KH TAB IX GRANT Xact X_KH <br><br>阻塞者——<br>对象 锁类型 模式 状态 所有者 索引 资源<br>ibank DB S GRANT Sess X_KH &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>ibank PAG IS GRANT Xact X_KH 1:125 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>ibank.dbo.X_KH TAB IS GRANT Xact X_KH &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>ibank.dbo.X_KH RID S WAIT Xact X_KH 1:125:6
 
select * from 之类的你把把放事务中做什么,不是明摆着有问题的嘛。<br>难道你的select 有什么特殊用途?
 
select放在事务中很正常啊,因为后面的update或insert语句要用到select的结果啊
 
你怎么还没有加 sql.clear
 
to jiangxidna:加不加差别不大,我觉得这不是问题的关键
 
在事务中使用 'select * from k_zhk' <br>如果如果量大,占用的时间过长,数据库会把整表锁住,占用更多的资源,以便尽快的完成任务。于是你的问题就产生了。<br>你这样编写确实非常怪异。
 
应该不是*的问题,我改为一个字段也是一样的,我的记录也不多<br>100条以内
 
最好用3个连接……<br>或者下面用querry的时候关闭上面的试试……
 
事情是这样的——<br>我现在在改造以前的一个旧程序,以前的数据库是oracle 8.1.7,我现在用sql server 2000<br>以前的程序运行正常。<br>但改造过程中很多用事务的地方都出现问题了,去掉事务后倒是可以正常执行,但又破坏了事件的原子性。<br>为什么加事务就会出问题?
 
是有这样问题,数据量大时,会死锁的
 
从你的描述来看“只有始终使用同一个Query才不会发生异常。”<br>说明Query1和Query3产生2个不同的连接,而且你的事务隔离级别应该是“读已提交”,<br>这样的话Query3正在等Query1完成,所以产生死锁!<br>你尝试一下你的事务隔离级别调整为“读脏数据”。。。看会不会通过。
 
to easykoala:<br>我对事务的隔离级别不是很懂,你能说明白一点嘛。<br>比如该如何设置?<br>谢谢
 
请说明你的连接控件。。。
 
我的所有数据控件都在一个data module(DM)里面,DM里面有唯一的一个database控件localdb,其他的数据控件都指向它
 
如果是BDE的TDatabase控件的话:<br>设置如下属性试试<br>Database1.HandleShared:=True;<br>//Database1.TransIsolation:=tiDirtyRead;<br>或者加入一个TSession控件,并且把TDatabase控件的SessionName指向它
 
我的程序确实是通过bde链接的<br>你的三种方法我都试过了,没有效果,还是死机。
 
按照你说的试了一下,不会产生你说的情况!<br>我用Delphi7,怎么试都通过。
 
学习,学习...
 
后退
顶部