如何修改clientdataset和datasetprovider属性
来使得服务器变为无状态?

解决方案 »

  1.   

    midas本身就支持无状态,但可以用一些事件中的参数保留状态,使之变成有状态。Like any COM object, transactional objects can maintain internal state across multiple interactions with a client. For example, the client could set a property value in one call, and expect that property value to remain unchanged when it makes the next call. Such an object is said to be stateful. Transactional objects can also be stateless, which means the object does not hold any intermediate state while waiting for the next call from a client.
    这是tclientdataset的帮助里的。
    主题是:Supporting state information in remote data modules
     DevGuide: Developing Database Applications
    Supporting state information in remote data modulesTopic Groups See AlsoThe IAppServer interface, which client datasets use to communicate with providers on the application server, is mostly stateless. When an application is stateless, it does not "remember" anything that happened in previous calls by the client. This stateless quality is useful if you are pooling database connections in a transactional data module, because your application server does not need to distinguish between database connections for persistent information such as record currency. Similarly, this stateless quality is important when you are sharing remote data module instances between many clients, as occurs with just-in-time activation or object pooling. SOAP data modules must be stateless.However, there are times when you want to maintain state information between calls to the application server. For example, when requesting data using incremental fetching, the provider on the application server must "remember" information from previous calls (the current record).Before and after any calls to the IAppServer interface that the client dataset makes (AS_ApplyUpdates, AS_Execute, AS_GetParams, AS_GetRecords, or AS_RowRequest), it receives an event where it can send or retrieve custom state information. Similarly, before and after providers respond to these client-generated calls, they receive events where they can retrieve or send custom state information. Using this mechanism, you can communicate persistent state information between client applications and the application server, even if the application server is stateless. For example, consider a dataset that represents the following parameterized query:SELECT * from CUSTOMER WHERE CUST_NO > :MinVal ORDER BY CUST_NOTo enable incremental fetching in a stateless application server, you can do the following: When the provider packages a set of records in a data packet, it notes the value of CUST_NO on the last record in the packet:TRemoteDataModule1.DataSetProvider1GetData(Sender: TObject; DataSet: TCustomClientDataSet);
    begin
      DataSet.Last; { move to the last record }
      with Sender as TDataSetProvider do
        Tag := DataSet.FieldValues['CUST_NO']; {save the value of CUST_NO }
    end; The provider sends this last CUST_NO value to the client after sending the data packet:TRemoteDataModule1.DataSetProvider1AfterGetRecords(Sender: TObject; 
                       var OwnerData: OleVariant);
    begin
      with Sender as TDataSetProvider do
        OwnerData := Tag; {send the last value of CUST_NO }
    end; On the client, the client dataset saves this last value of CUST_NO:TDataModule1.ClientDataSet1AfterGetRecords(Sender: TObject; var OwnerData: OleVariant);
    begin
      with Sender as TClientDataSet do
        Tag := OwnerData; {save the last value of CUST_NO }
    end; Before fetching a data packet, the client sends the last value of CUST_NO it received:TDataModule1.ClientDataSet1BeforeGetRecords(Sender: TObject; var OwnerData: OleVariant);
    begin
      with Sender as TClientDataSet do
      begin
        if not Active then Exit;
        OwnerData := Tag; { Send last value of CUST_NO to application server }
      end;
    end; Finally, on the server, the provider uses the last CUST_NO sent as a minimum value in the query:TRemoteDataModule1.DataSetProvider1BeforeGetRecords(Sender: TObject; 
                        var OwnerData: OleVariant);
    begin
      if not VarIsEmpty(OwnerData) then
        with Sender as TDataSetProvider do
          with DataSet as TSQLDataSet do
          begin
            Params.ParamValues['MinVal'] := OwnerData;
            Refresh; { force the query to reexecute }
        end;
    end;