Problemas com DataSnap 2010

Delphi

28/04/2010

Olá pessoal ...   To com um problema na utilização do DataSnap do D2010.   Eu migrei um dos meus sistemas que era em D7 para D2010, eu utilizava Multi-Camadas no D7, mas resolvi optar por usar a nova tecnologia do DataSnap. Até ai tudo bem, só que depois que coloquei na linha de produção comecei a ter alguns problemas, que eu não tinha, as vezes o meu sistema tentava pegar uma informação do banco de dados e não encontrava, me dava a mensagem “Can not open a Resultset”, ( eu uso PostgresSQL 8.4, com Zeos 7 ),  entre outras mensagens, eu olhava no meu log, tinha SQL correto, que não conseguia ser executado. Como disse não tinha esse problema ... Ontem fiz um pequeno Sistema só para testar a minha conexão ... O que eu fiz .   Criei um Servidor com a estrutura parecida com que eu utilizo em linha de produção basicamente é isto Criei DataModulo, e um DSServerModule, no meu DataModule coloquei o componente DSServer, um DSTCPServerTransport, um DSServerClass e um ZConnection, o meu DSServerClass esta com a propriedade LifeCycle = Session, até aqui ok .... no meu DSServerModule criei três funções. function GetTime: String; // Só faz pegar a hora.  function RunSQL(lcSQL: String): boolean; // Vai Executar um Update ou Insert  function SQLToStr(lcSQL: String): String; // Retorna um Select, não um bloco só um campo.   Criei um Sistema Cliente, que pega essa data, executa um insert, pega o SELECT, conecta e disconecta  ... tem um time que executa isto ...   Ontem anoite deixei rolando . abri o Servidor abri quatro desses clientes ... para cada um fazer uma dessas funções ... coloquei o time para 2 segundos ... olhei de manhã e nenhum erro ... Fiz outro teste colocando o time para meio segundo . começou os problemas ...  esses erros que comentei de não poder abrir o ResultSet .... falta de Sincronismo com o banco . a ponto de desconectar o meu Servidor ... mesmo com os erros tratados ... perdeu a conexão, tendo que abrir um novo servidor, aumentei para 1 segundo, o servidor não travou ... mas de vez enquando o SELECT não era retornado ... quando abria mas de um Sistema Cliente ... para pegar o SELECT na mesma tabela, quando eu abri quatro ... somente para o SELECT voltei a ter problema deu este erro “SQL Error: message contents do not agree with length in message type "T" server sent data ("D" message) without prior row description ("T" message)”.   E não consegui mas manipular as minhas funções de acesso a banco.   Não sei se estou configurando algo errado ... ou onde esta este problema ...   Fico esperando a ajuda de vcs.
Jardson Cleyton

Jardson Cleyton

Curtidas 0

Respostas

Jardson Cleyton

Jardson Cleyton

28/04/2010

Vou mandar o Codigo das Units que criei tanto no Servidor como no Cliente ...   SERVIDOR   unit Main;   interface   uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, StdCtrls, AppEvnts;   type   TForm1 = class(TForm)     mmoError: TMemo;   private     { Private declarations }   public     { Public declarations }   end;   var   Form1: TForm1;   implementation   {$R *.dfm}   end.     unit Useful;   interface   uses ZConnection, Dialogs, SysUtils, DB, ZDataSet;   type   TUseful = class   strict private     class var FoConn: TZConnection;     class procedure SetConn(loConn: TZConnection);   public     class function GetConn: TZConnection;     class function ConnectDataBase(loConn: TZConnection): boolean;     class function RunSQL(lcSQL: String): Boolean;     class function SQLToStr(lcSQL: String): String;   end;   implementation   uses Main;   { TUseful }   class function TUseful.ConnectDataBase(loConn: TZConnection): boolean; begin   try     loConn.Database := 'jcs_bdsge';     loConn.User     := 'postgres';     loConn.Password := '761270';     loConn.Port     := 5432;     loConn.Protocol := 'postgresql-8';     loConn.HostName := '192.168.1.201';       loConn.Connected := true;     SetConn(loConn);     result := true;   except on e: exception do   begin     raise EDatabaseError.Create(loConn.Database + #13#10 +                 loConn.User + #13#10 +                 loConn.Password + #13#10 +                 IntToStr(loConn.Port) + #13#10 +                 loConn.Protocol + #13#10 +                 loConn.HostName + #13#10 +                 e.Message);   end;   end; end;   class function TUseful.GetConn: TZConnection; begin   if FoConn <> nil   then Result := FoConn   else raise EDataBaseError.Create('Conexão inválida'); end;   class function TUseful.RunSQL(lcSQL: String): Boolean; begin   if GetConn.ExecuteDirect(lcSQL)   then result := true   else begin          result := false;          form1.mmoError.Lines.Add(DateToStr(Date) + ' ' + TimeToStr(Time));          form1.mmoError.Lines.Add('Message  : Erro ao tentar inserir ' + lcSQL);          form1.mmoError.Lines.Add('----------------------------------------------------------' +            '----------------------------------------------------------------');        end; end;   class procedure TUseful.SetConn(loConn: TZConnection); begin   FoConn := loConn; end;   class function TUseful.SQLToStr(lcSQL: String): String; var   loQry: TZQuery; begin   loQry := TZQuery.Create(nil);   loQry.Connection := GetConn;   loQry.Close;   loQry.SQL.Clear;   loQry.SQL.Add(lcSQL);     try     loQry.Open;     result := loQry.Fields[0].AsString;   except on e: Exception do     begin       result := '';       form1.mmoError.Lines.Add(DateToStr(Date) + ' ' + TimeToStr(Time));       form1.mmoError.Lines.Add('Message  : ' + E.Message);       form1.mmoError.Lines.Add('ClassName: ' + E.ClassName);       form1.mmoError.Lines.Add('----------------------------------------------------------' +         '----------------------------------------------------------------');     end;     end;     FreeAndNil(loQry); end;   end.       unit DModule;   interface   uses   SysUtils, Classes, DSCommonServer, DSServer, DSTCPServerTransport, ZConnection, Forms;   type   TDataModule2 = class(TDataModule)     DSTCPSTSGE: TDSTCPServerTransport;     DSSSGE: TDSServer;     DSServerClass1: TDSServerClass;     procedure DSServerClass1GetClass(DSServerClass: TDSServerClass;       var PersistentClass: TPersistentClass);   private     { Private declarations }   public     { Public declarations }   end;   var   DataModule2: TDataModule2;   implementation   uses Useful, SMMainClass;   {$R *.dfm}   procedure TDataModule2.DSServerClass1GetClass(DSServerClass: TDSServerClass;   var PersistentClass: TPersistentClass); begin   PersistentClass := TDSServerModule1; end;   end.     unit SMMainClass;   interface   uses   SysUtils, Classes, DSServer, ZConnection;   type   TDSServerModule1 = class(TDSServerModule)     ZConJCS_BDSGE: TZConnection;     procedure DSServerModuleCreate(Sender: TObject);   private     public     function GetTime: String;     function RunSQL(lcSQL: String): boolean;     function SQLToStr(lcSQL: String): String;   end;   implementation   uses Useful;   {$R *.dfm}   { TDSServerModule1 }   procedure TDSServerModule1.DSServerModuleCreate(Sender: TObject); begin   TUseful.ConnectDataBase(ZConJCS_BDSGE); end;   function TDSServerModule1.GetTime: String; begin   result := TimeToStr(Time); end;   function TDSServerModule1.RunSQL(lcSQL: String): boolean; begin   result := TUseful.RunSQL(lcSQL); end;   function TDSServerModule1.SQLToStr(lcSQL: String): String; begin   result := TUseful.SQLToStr(lcSQL); end;   end.     Como  eu disse é uma aplicação simples ... no Servidor só tem essas quatro units ... e como foi sugerido pelo Bruno coloquei o meu conector de banco no ServerModule.   APLICAÇÃO CLIENTE   unit Main;   interface   uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, WideStrings, DbxDatasnap, DB, SqlExpr, StdCtrls, ExtCtrls;   type   TOption = (opCatchDate, opInsert, opSelect, opConnection);     TForm2 = class(TForm)     Button1: TButton;     Button2: TButton;     Button3: TButton;     Memo1: TMemo;     SQLConnection1: TSQLConnection;     Timer1: TTimer;     Button4: TButton;     procedure Button1Click(Sender: TObject);     procedure Timer1Timer(Sender: TObject);     procedure Button2Click(Sender: TObject);     procedure Button3Click(Sender: TObject);     procedure Button4Click(Sender: TObject);   private     FoOption : TOption;   public     { Public declarations }   end;   var   Form2: TForm2;   implementation   uses ClassProxy;   {$R *.dfm}   procedure TForm2.Button1Click(Sender: TObject); begin   FoOption := opCatchDate;   Timer1.Enabled := true; end;   procedure TForm2.Button2Click(Sender: TObject); begin   FoOption := opInsert;   Timer1.Enabled := true; end;   procedure TForm2.Button3Click(Sender: TObject); begin   FoOption := opSelect;   Timer1.Enabled := true; end;   procedure TForm2.Button4Click(Sender: TObject); begin   FoOption := opConnection;   Timer1.Enabled := true; end;   procedure TForm2.Timer1Timer(Sender: TObject); var   loClass : TDSServerModule1Client;   lcSQL, lcTemp: String; begin   if not SQLConnection1.Connected   then SQLConnection1.Connected := true;     loClass := TDSServerModule1Client.Create(SQLConnection1.DBXConnection);   case FoOption of     opCatchDate : Memo1.Lines.Add('Hora   : ' + loClass.GetTime);     opInsert    : begin                     lcSQL := 'INSERT INTO TSGETES (TES_VAL) VALUES (' + QuotedStr(TimeToStr(Time)) + ')';                     Memo1.Lines.Add('Insert : ' + BoolToStr(loClass.RunSQL(lcSQL)) + ' | ' + lcSQL);                   end;     opSelect    : Memo1.Lines.Add('Select : ' + loClass.SQLToStr('SELECT MAX(TES__ID) FROM TSGETES'));     opConnection: if SQLConnection1.Connected = true                   then begin                          SQLConnection1.Connected := false;                          try                            SQLConnection1.Connected := true;                            Memo1.Lines.Add('Conectar : Conectado com sucesso! ' + TimeToStr(Time));                          except on e : exception do                            Memo1.Lines.Add('Conectar : Erro ao tentar conectar | ' + TimeToStr(Time) + ' '+ e.Message);                          end;                        end;                     end;   FreeAndNil(loClass); end;   end.   Essa Aplicação só tem uma unit mesmo e a unit gerado pelo SQLConnection para minha conexão com o DataSnap.    
GOSTEI 0
POSTAR