COM+中间层多了三行代码,系统就报错“分步式事务已完成,请将此会话登记到新事务或NULL事务中”

beginer001 2003-09-05 05:26:08
在一个方法中,我准备多次修改DM.cds.CommandText属性来取参数值,

DM.cds.Close;
DM.cds.CommandText := '...';
DM.cds.Open;
sName := DM.cds.Fields[0].AsString;

...
...

但当我第二次调用时,
DM.cds.Close;
DM.cds.CommandText := '...';
DM.cds.Open;//调试时系统执行到这一步就愣住了,半天才报个错“分步式事务已完
//成,请将此会话登记到新事务或NULL事务中”

如果屏蔽掉第二次调用的三句代码,程序运行正常,痛苦啊!
(注:几次的SQL均在SQL Server中测试通过)
...全文
155 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
beginer001 2003-09-10
  • 打赏
  • 举报
回复
再次谢过 :)
beginer001 2003-09-10
  • 打赏
  • 举报
回复
问题解决了,是由于程序处理流程逻辑不合理原因造成的,我在这个方法中调用了另外一个对象的一个更新方法,该方法更新了执行超时SQL语句的记录,反过来我在当前方法中又取这条记录,导致SQL反应迟钝(可能前面的更新还没进行物理更新),今天心情特爽,功能已完成,现在正在优化这部分程序,
敢问楼上几位都是在搞d/com+编程吗?现在这种搭配行情如何?我准备走人喽,不过得等到明年,答应老板的
leapmars 2003-09-10
  • 打赏
  • 举报
回复
Mark
Miracle 2003-09-10
  • 打赏
  • 举报
回复
超时已过期 的原因是我把ConnectionTimeout改小了的缘故,但改大后又出现原来的错误提示了
=======
从描述上看很可能就是连接数据库失败的原因,ConnectionTimeout改小,就无法及时连接数据库,导致“超时已过期”;而改的足够大,数据库是能连上了,但分布式事务却已经被结束,此时出现另一个错误,就是“分步式事务已完成,请将此会话登记到新事务或NULL事务中”
Miracle 2003-09-10
  • 打赏
  • 举报
回复
超时已过期一般是发生在ADOConnection打开的时刻。你大概是通过机器名来访问SQLServer的吧?换用IP地址访问。这种问题在写C/S结构的程序的时候经常遇到,通过IP访问的速度要比通过机器名快得多(不需要进行名称解析和Windows安全性验证)
beginer001 2003-09-09
  • 打赏
  • 举报
回复

对了,我把我的环境说一下,两台机器,一台临时数据库服务器(同事的)(SQL Server/XP),我的(Win2000)作中间层服务器,客户端也在我机器上运行
beginer001 2003-09-09
  • 打赏
  • 举报
回复
shsunb(我怕来不及):
我按你说的,取消了调试状态,把组件连同组件包一起删除了,并把服务器\客户端的所有编译生成文件删除,然后重新编译、安装,

此时系统不报原来的错了,改为报:“超时已过期”,请指教
冰杯可乐 2003-09-09
  • 打赏
  • 举报
回复
怎么可能是超时呢,SQL设置适当的话效率很高的,浏览几千万笔纪录几秒钟内就能完成,所以一般组件不会超时的。
还有如果是组件之间调用的话也可能会出现这种问题,可以在第一个组件,即根事务创建者设置调试,同时打开其它组件相关单元,即可自动调试到其他组件中去。
冰杯可乐 2003-09-09
  • 打赏
  • 举报
回复
类似的问题我也碰到过,不过早解决了
我认为还是组件问题。
这里假设组件执行的是写操作(读操作一般不会碰到该问题),且是本机执行(如果组件执行在其他机器则一定要确保midas.dll在system32目录下),组件在Delphi中的属性不要设为调试状态,卸载并删除原组件dll,重新编译,安装,问题就会没有了。
有问题再贴出来。
冰杯可乐 2003-09-09
  • 打赏
  • 举报
回复
有问题很正常,关键是你自己能否有一套解决思路。
看了你的代码,如果iIoneObj不能一次调用就释放的话,试试我改的:
try
try
DM.cds.Close;
DM.cds.CommandText := ...;
DM.cds.Open;
...
OleCheck(ObjectContext.CreateInstance(Class_oneObj, IoneObj, iIoneObj));
iIoneObj.ExecSQL('...');
...
iIoneObj.ExecSQL('...');

if iIoneObj <> nil then iIoneObj := nil;//我加的


...
DM.cds.Close;
DM.cds.CommandText := ...;
DM.cds.Open;//这次调用的时候时间特别长,导致超时
...
DM.cds.Close;
DM.cds.CommandText := ...;
DM.cds.Open;

OleCheck(ObjectContext.CreateInstance(Class_oneObj, IoneObj, iIoneObj));//我加的

iIoneObj.ExecSQL('...');
if iIoneObj <> nil then iIoneObj := nil;//我加的

...
SetComplete;
except
SetAbort;
raise;
end;
finally
iIoneObj := nil;
iItwoObj := nil;
end;
beginer001 2003-09-09
  • 打赏
  • 举报
回复

试了,又错了,太痛苦了
冰杯可乐 2003-09-09
  • 打赏
  • 举报
回复
还要注意adocon的问题。你是一直连接着还是每次需要时再连接的?
执行SQL最好用adoquery,然后将数据集赋给cds,让cds彻底与数据库断开连接
冰杯可乐 2003-09-09
  • 打赏
  • 举报
回复
midas.dll两台电脑的system32下都应该有的!

如果还不可以,可能是数据库造成的了,建议你将跟踪到的最终数据库执行的sql语句在查询分析器中测试一下执行效率,然后写个简单的组件,只执行该sql语句对比一下效率。如果还找不出问题所在,建议你考虑重新设计数据库对应表的索引,组件端重新设计。
beginer001 2003-09-09
  • 打赏
  • 举报
回复
超时已过期 的原因是我把ConnectionTimeout改小了的缘故,但改大后又出现原来的错误提示了
猛禽 2003-09-08
  • 打赏
  • 举报
回复
楼上高人,建议一试:)
Miracle 2003-09-08
  • 打赏
  • 举报
回复
SELECT TOP 1 FID FROM tGroup WHERE FClass=2 AND SUBSTRING(FCode,1,4)='0006'

这个命令不科学,SUBSTRING指令无法利用索引,要判断记录是否符合调剂就必须进行TableScan,严重耗时。从参数来看,应该是判断前四个字符是否为0006,那么SQL更改为

SELECT TOP 1 FID FROM tGroup WHERE FClass=2 AND FCode like '0006%'

即可有效利用FCode字段上的索引,大幅度提高效率,缩短执行时间。试一下,Good Luck!
Miracle 2003-09-08
  • 打赏
  • 举报
回复
典型的执行超时。
beginer001 2003-09-08
  • 打赏
  • 举报
回复
该方法框架如下:
try
try
DM.cds.Close;
DM.cds.CommandText := ...;
DM.cds.Open;
...
OleCheck(ObjectContext.CreateInstance(Class_oneObj, IoneObj, iIoneObj));
iIoneObj.ExecSQL('...');
...
iIoneObj.ExecSQL('...');
...
DM.cds.Close;
DM.cds.CommandText := ...;
DM.cds.Open;//这次调用的时候时间特别长,导致超时
...
DM.cds.Close;
DM.cds.CommandText := ...;
DM.cds.Open;
iIoneObj.ExecSQL('...');
...
SetComplete;
except
SetAbort;
raise;
end;
finally
iIoneObj := nil;
iItwoObj := nil;
end;

那位帮帮忙,很急啊
beginer001 2003-09-08
  • 打赏
  • 举报
回复
自己UP
beginer001 2003-09-08
  • 打赏
  • 举报
回复
我在组件管理器-〉时间查看器-〉应用程序中发现如下事件
类型 来源 分类 事件
信息 MSDTC CM 4156
事件详细描述:
字串信息: Session idle timeout over, tearing down the session。

那位高手能根据这个事件信息解决一下,提示中的Session时间指的是程序中的什么时间
加载更多回复(10)

1,594

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧