起步软件技术论坛-X3

 找回密码
 立即注册
搜索
查看: 733|回复: 12

【搞定】网络连接失败时事务没有完全回滚,请问应如何处理?**

[复制链接]
发表于 2007-3-15 10:14:44 | 显示全部楼层 |阅读模式
请看如下代码:
procedure TMainForm.DtSBkyhqzdlrBeforeApplyUpdates(DataSet: TDataSet);
var
  h: TTransActionHandle;
  pDelta: TDeltaDataSet;
  pField: TDataField;
begin
  pDelta := TDeltaDataSet.Create(DataSet);
  pField := pDelta.FieldByName('YHJLBH');
  with DataSet do
  try
    h := Connection.Transaction.Start(False);
    try
      case pDelta.UpdateKind of
        TUpdateKind.ukModify:
        begin
          if pDelta.FieldModified(pField) then
          begin
            Connection.ExecuteSQL('update yhjl set sfhs=''0'' where bh='''+ Variants.VarToStr(pField.OldValue) +'''');
            Connection.ExecuteSQL('update yhjl set sfhs=''1'' where bh='''+ Variants.VarToStr(pField.NewValue) +'''');
          end;
        end;
        TUpdateKind.ukInsert:
        begin
          Connection.ExecuteSQL('update yhjl set sfhs=''1'' where bh='''+ Variants.VarToStr(pField.NewValue) +'''');
        end;
        TUpdateKind.ukDelete:
        begin
          Connection.ExecuteSQL('update yhjl set sfhs=''0'' where bh='''+ Variants.VarToStr(pField.OldValue) +'''');
        end;
      end;
      Connection.Transaction.Commit(h);
    except
      on E: Exception do
      begin
        Connection.Transaction.Rollback(h);
        XTHSK.TXTHSK.ShowExcept(E.Message);
      end;
    end;
  finally
    pDelta.Free;
  end;
end;

DtSBkyhqzdlr是个TDataSetBroker,它连接的是yhqzd表,
我是要在保存yhqzd表的同时更新yhjl表中的sfhs字段的值。
这样的写法有没有错误?
我在测试时发现在Connection.Transaction.Commit(h)执行前网络断开,
yhjl表中的sfhs字段的值没有被更新;但在Connection.Transaction.Commit(h)执行后网络断开,yhjl表中的sfhs字段的值被更新,但yhqzd表中的记录没有保存。
请问应该如何处理?
回复

使用道具 举报

发表于 2007-3-15 11:32:36 | 显示全部楼层
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-3-15 12:12:34 | 显示全部楼层
这两个帖子我都看了,感觉和我的问题不一样。
因为如果正好执行完Connection.Transaction.Commit(h)语句时网络发生故障,
此时事务是不回滚的,因为已经提交了,yhjl表中的sfhs字段的值已经更新了。
回复 支持 反对

使用道具 举报

发表于 2007-3-15 13:39:50 | 显示全部楼层
网络发生故障是指网络断了吧!那肯定无法再执行下面的语句了,也就不能再回滚了!事务回滚也是要在网络正常的而又提交失败的情况下!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-3-15 14:48:56 | 显示全部楼层
是呀,就是网络经常断!
那这种情况下如果解决事务的回滚呢?难道就没有办法解决这种情况了吗?
回复 支持 反对

使用道具 举报

发表于 2007-3-15 15:19:05 | 显示全部楼层
如果网络中断,导致不能连接到数据库,则会进行提示是否要重试,如果不要重试,则退出整个系统;如果重试,则会重试连接到数据库,但如果仍然不能连接,则重复进行提示直到连接上或由用户取消连接以退出系统!
具体方法要找下!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-3-15 16:26:41 | 显示全部楼层
那就像我上面说的,正好执行完Connection.Transaction.Commit(h)语句时网络中断,而又不重试,退出系统的话,
是不是就会造成一个表已经更新,而另一个表还没有更新的情况呢。
因为Connection.Transaction.Commit(h)执行之后yhjl表中的数据已经更新,而yhqzd表还没有更新。
有没有什么好方法呀?这个问题我想了很久了,总是搞不明白。盼望赐教
回复 支持 反对

使用道具 举报

发表于 2007-3-15 16:45:01 | 显示全部楼层
在DtSBkyhqzdlrBeforeApplyUpdates事件之前系统会创建一个事务,因此你应该把这段代码里面的有关事务的代码都去掉,而用系统的事务处理!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-3-15 17:09:14 | 显示全部楼层
这么说我是画蛇添足了,呵呵。
我以前没有写事务,试过好像下面这条语句
Connection.ExecuteSQL('update yhjl set sfhs=''0'' where bh='''+ Variants.VarToStr(pField.OldValue) +'''');
执行后,yhjl表就立即更新了。
是不是不在默认的事务里呢?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-3-15 17:36:42 | 显示全部楼层
请问如何写法才能保证
'update yhjl set sfhs=''0'' where bh='''+ Variants.VarToStr(pField.OldValue) +'''')
在BeforeApplyUpdate事件之前系统自动创建的事务里呢。
我测试过,按我现在的写法不行,
Connection.ExecuteSQL('update yhjl set sfhs=''0'' where bh='''+ Variants.VarToStr(pField.OldValue) +'''');
执行后yhjl表就立即更新了。
困惑呀!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Justep Inc.

GMT+8, 2025-6-18 19:56 , Processed in 0.041278 second(s), 15 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表