起步软件技术论坛-X3

 找回密码
 立即注册
搜索
查看: 340|回复: 11

【搞定】流程事件的问题

[复制链接]
发表于 2007-4-18 09:02:01 | 显示全部楼层 |阅读模式
我在AfterFlowOut事件写如下代码
procedure TYMJFSYWLC.ProcUnitYMJCWQRYWGNAfterFlowOut(Sender: TObject; Command: TFlowOutCommand);
var
  Connection: TConnection;
  lTransHandle: TTransactionHandle;
  lQuery:TQuery;
  NewGuid,s,id,SQDW,WLBM:string;
  RKSL:double;
begin
  //处理库存
  try
    id := Command.FlowControl.Flow.ID ;
  except
    Business.Forms.Dialogs.ShowMessage( '流程数据错误!');
    exit;
  end;

  Connection:=TConnection.Create(nil);
  Connection.ConnectionString:='DATABASEURL=Biz:\GYLGLXT\YWSJK.Database';
  Connection.Open;
  try
    lQuery:=TQuery.Create(nil);
    lQuery.Connection:=Connection;
    lQuery.CommandText:='select CKMXB.*,A.SQDW from CKMXB inner join YMJB A on CKMXB.GLID=A.ID where CKMXB.TKS>0 and A.id='''+id+'''';
    lQuery.Open;

    lTransHandle := Connection.Transaction.Start(False);
    while not lQuery.Eof do
    begin
      SQDW:=lQuery.FieldByName('SQDW').AsString;
      WLBM:=lQuery.FieldByName('WLBM').AsString;
      RKSL:=lQuery.FieldByName('TKS').AsFloat*lQuery.FieldByName('HSBL').AsFloat;
      NewGUID:=Business.System.JSCommon.CreateGUIDStr;

      s:='if((select count(id) from WLKCB where CFCK='''+SQDW+''' and WLBM='''+WLBM+''')>0)';
      s:=s+'update WLKCB set KCL=KCL+'+SysUtils.FloatToStr(RKSL)+' where CFCK='''+SQDW+''' and WLBM='''+WLBM+'''';
      s:=s+' else insert into WLKCB(ID,WLBM,DJ,CFCK,WLZT,CGFS,KCL,RKSJ,MEMO) select '''+NewGUID+''' as ID,WLBM,DJ,'''+SQDW+''' as CFCK,WLZT,CGFS,'+SysUtils.FloatToStr(RKSL)+' as KCL,getdate() as RKSJ,MEMO from WLKCB,YMJB where WLKCB.CFCK=YMJB.CKCK and YMJB.ID='''+ID+''' and WLKCB.WLBM='''+WLBM+'''';
      Connection.ExecuteSQL(s);
      lQuery.Next;
    end;
    Connection.Transaction.Commit(lTransHandle);
  except
    Connection.Transaction.RollBack(lTransHandle);
    Command.Accept:=False;
    Raise;
  end;
  lQuery.Free;
  Connection.Free;

end;

进行库存处理,现在问题是如果数据库操作中出现异常,而流程已经流转下去了,这种情况怎么处理?

我的意思是应该在哪个事件中处理库存,可以保证出错时流程不能流转,或者有什么可以变通的方案。
回复

使用道具 举报

 楼主| 发表于 2007-4-18 09:55:49 | 显示全部楼层
没人吗
回复 支持 反对

使用道具 举报

发表于 2007-4-18 10:21:30 | 显示全部楼层
try
    id := Command.FlowControl.Flow.ID ;
  except
    Business.Forms.Dialogs.ShowMessage( '流程数据错误!');
    exit;
  end;
当出错时候,except截获了错误,然后exit,这个事件就正常结束了,当然流程可以继续了,但是数据没有保存

应该是
  try
    id := Command.FlowControl.Flow.ID ;
  except
    Business.Forms.Dialogs.ShowMessage( '流程数据错误!');
    sysutils.Abort;
  end;
回复 支持 反对

使用道具 举报

发表于 2007-4-18 10:22:50 | 显示全部楼层
而且在这个事件中不要再次启动事务
因为在流程中已经启动了事务
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-4-18 14:10:23 | 显示全部楼层
我是觉得库存处理的操作放在AfterFlowout事件不合适,因为此时已不能控制流程流转,但放在其它事件中好像也不行,当用户多次尝试流转确认时会造成重复处理,想请问有没有好的解决办法?

怎么引用流程启动的事务来实现数据回滚?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-4-18 14:12:00 | 显示全部楼层
try
    id := Command.FlowControl.Flow.ID ;
  except
    Business.Forms.Dialogs.ShowMessage( '流程数据错误!');
    sysutils.Abort;
  end;

这个不是主要的,因为是几乎不可能发生的情况
回复 支持 反对

使用道具 举报

发表于 2007-4-18 15:16:35 | 显示全部楼层
其实,只要流程和业务数据库放到一个事务中,流转过程自动会启动事务,如果中间出错了,自然整个事务就会回滚,包括流程数据和业务数据都会回滚的
有关事务,请参考 http://wiki.justep.cn/mywiki/moi ... t=%28transaction%29
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-4-18 15:37:17 | 显示全部楼层
我的版本是2435,在功能层上不好做,我是在流程层用TConnection和TQuery进行业务数据操作,好像不可以用流程启动的事务
回复 支持 反对

使用道具 举报

发表于 2007-4-18 15:52:17 | 显示全部楼层
都是可以用的

流程控制数据与业务数据在同一个事务中提交(2507版本之前)
缺省流程控制数据和业务数据不在同一个事务中,如果需要他们放到同一个事务中,则需要在功能窗体的OnCreate事件中加入代码

FlowBroker1.FlowControl.FlowManager.Transaction := DataSetBroker1.DataSet.Connection.Transaction;
然后,直接截获流程事件就可以了,不需要调用Transaction.Start之类的事务控制,这些控制都是流程来做的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-4-18 17:24:57 | 显示全部楼层
procedure TYMJCWQR.BizFormCreate(Sender: TObject);
begin
  FlowBroker.FlowControl.FlowManager.Transaction := DataSetBrokerMain.DataSet.Connection.Transaction;
end;


procedure TYMJCWQR.FlowBrokerBeforeFlowOut(Sender: TObject; Command: TFlowOutCommand);
var
  Connection: TConnection;
  lTransHandle: TTransactionHandle;
  DsMain,DsMX,DsKC:TDataSet;
  //lQuery:TQuery;
begin
  DsMain:=DataSetBrokerMain.DataSet;
  DsMX:=DataSetBrokerMX.DataSet;
  DsKC:=DataSetBrokerKC.DataSet;

  if not DataSetBrokerMain.DataSet.Active then DataSetBrokerMain.DataSet.Active:=True;
  if not DataSetBrokerMX.DataSet.Active then DataSetBrokerMX.DataSet.Active:=True;
  if not DataSetBrokerKC.DataSet.Active then DataSetBrokerKC.DataSet.Active:=True;

  Connection:=DsKC.Connection;
  try
    DsMX.First;
    while not DsMX.Eof do
    begin
      //if DsKC.State in [TDataSetState.dsInsert,TDataSetState.dsEdit] then
      //  DsKC.ApplyUpdates;
      with (DsKC as TSQLDataSet) do
      begin
        Filter:='WLBM='''+DsMX.FieldByName('WLBM').AsString+''' and CFCK='''+DsMain.FieldByName('SQDW').AsString+'''';
        Filtered:=True;
      end;
      if DsKC.RecordCount>0 then
      begin
        DsKC.Edit;
        DsKC.FieldByName('KCL').AsFloat:=DsKC.FieldByName('KCL').AsFloat+DsMX.FieldByName('TKS').AsFloat;
      end else
      begin
        DsKC.Append;
        DsKC.FieldByName('WLBM').AsString:=DsMX.FieldByName('WLBM').AsString;
        DsKC.FieldByName('KCL').AsFloat:=DsMX.FieldByName('TKS').AsFloat;
        DsKC.FieldByName('CFCK').AsString:=DsMain.FieldByName('SQDW').AsString;
        DsKC.FieldByName('CGFS').AsInteger:=1;
      end;
      DsKC.ApplyUpdates(-1);
      DsMX.Next;
    end;
  except
    Command.Accept:=False;
    Raise;
    SysUtils.Abort;
  end;

end;

已经改为功能层做,这样当红色部分提交出错,已经提交的数据会自动回滚吗?

该截取哪个事件的问题还是没有解决,请支招
回复 支持 反对

使用道具 举报

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

本版积分规则

小黑屋|手机版|Justep Inc.

GMT+8, 2025-1-16 07:52 , Processed in 0.041560 second(s), 15 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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