• 实现数据驱动的业务流程


    1,需求描述

    某项目收集上千个设备的数据,前端程序采集数据后写入数据库。

    当某些特定数据满足触发条件时,需要后端程序即时发起业务处理流程。

    2,技术方案

    2.1 定时扫描数据库

    显然,可以采用后端程序定时扫描数据库的办法。此法简单易行,但缺点也很明显,不能满足业务处理的即时性要求。

    如果扫描周期过长,则响应延时差;如果扫描周期过短,则数据库压力加大,可能波及整个系统。

    2.2 数据库驱动业务

    方案2.1是由后台程序主动发起,因此无法发起时机是随机的,相当于在瞎猜。

    本方案则采用由数据库发起的思路,这也是很容易想到的。因为数据库对于数据是否变化,以及变化是否满足业务发起条件能在第一时间内加以判别。

    采用表触发器可以在数据提交后判断是否需要后台程序处理。如果需要,就向后台程序发送消息,后台程序收到消息后,立即开始执行业务流程。这样就实现了由数据驱动的业务流程。

    该方案避免了数据扫描,对数据库压力最小,业务处理响应也是即时性的。

    3,SQLServer+Delphi实现

    以下以SQLServer2005和Delphi7为例,具体实现由数据驱动的业务流程。主要步骤包括:

    数据库表建立触发器,在触发器中发送消息

    后台程序中接收消息,执行处理。

    3.1 数据库发送消息函数

    首先,要在SQLServer2005数据库中建立发送消息的函数SendHttpMsg。

    create  PROCEDURE [dbo].[SendHttpMsg]
            @Params varchar(30) = ''    
    AS
        DECLARE @obj INT
        DECLARE @sUrl varchar(200)
        DECLARE @response INT
        
        SET @sUrl = 'http://www.xxx.net:30008/QA?' +@Params  
        
        EXEC sp_OACreate 'MSXML2.ServerXMLHTTP', @obj OUT
        EXEC sp_OAMethod @obj,'open', NULL, 'GET', @sUrl, false
        EXEC sp_OAMethod @obj,'send', null
    
    RETURN

    3.2 数据库表触发器

    在要监控的表上创建触发器,调用SendHttpMsg函数,发送101消息

    CREATE TRIGGER [dbo].[tr_em_test_sendCmd]
    ON [dbo].[EM_Test]
    AFTER UPDATE
    AS
    BEGIN
    
          --状态变化,更新显示
          if  @parkingStatus2 <> @parkingStatus0 begin
                EXEC SendHttpMsg  @Params='cmd=101'
          end 
    
    END

    3.3 后台程序监听处理

    Delphi7中可以使用TIdHTTPServer组件来监听Http消息。 绑定30008端口。在其OnCommandGet事件处理过程中执行代码:

    procedure TfHttp.IdHTTPServer30008CommandGet(AThread: TIdPeerThread;
      ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
    var
      cmd: string;
    begin
      try
    
        cmd := ARequestInfo.Params.Values['cmd'];
    
        if cmd='101' then begin
          self.Timer_ProcHttpMsg.Enabled := True;
        end;
    end;

    然后,在Timer_ProcHttpMsg的定时器事件中执行相应的业务逻辑即可。

    3.4 注意事项

    注意不能在OnCommandGet事件处理过程中直接调用业务逻辑函数,否则将导致数据库访问超时错误。

    原因如下:

    1. 数据表记录状态变化à
    2. 数据表的行update触发器启动à
    3. DB发送Http消息à
    4. EXE的Http服务端口接收到消息à
    5. EXE查询数据表统计信息à
    6. EXE更新业务信息à
    7. EXE的Http服务端口处理完毕à
    8. 数据表的行update触发器完成à
    9. 记录提交à

     

    以上处理流程中第5步实际上无法完成,因为统计查询必须等待第9步完成才能实施。

    此处关键是要将第9步记录提交放到第5步之前。

    而第9步记录提交依赖于第7步的Http调用返回。

    因此问题明确了,以上流程中第5、6步不应该在EXE的Http服务端口处理事件中执行,而是应该另开线程,以便让Http服务端口处理事件迅速返回,从而使数据表记录变更得以快速提交。

     

    实际解决方案是,在EXE的Http服务端口处理事件中启动一个定时器事件,使统计和显示操作延后执行即可。

  • 相关阅读:
    js中的this指针(五)
    一个链式调用 setTimeout的例子
    js中的this指针(四)
    js中的this指针(三)
    NOJ 爱过
    Greatest Greatest Common Divisor HD5207
    Greatest Greatest Common Divisor HD5207
    Greatest Greatest Common Divisor HD5207
    Greatest Greatest Common Divisor HD5207
    Four Inages Strateg
  • 原文地址:https://www.cnblogs.com/jackkwok/p/12071359.html
Copyright © 2020-2023  润新知