ClientDataSet 怪问题,请高手帮忙!!!!(100分)

  • 主题发起人 主题发起人 Lihang001
  • 开始时间 开始时间
如果没有人机交互的过程就叫一次。可以一起执行。
另外就是在本地建立一定的数据缓冲。把一些数据存放在本地,定时和服务器进行同步。
三层应用本身就是一种以时间换空间的方法。
即每一个用户的速度都降低一点,但是可以连接的用户数极大的提好。而且安全性方面和可维护性方面也有极大的提高。
连接虽然比较费时间,但是创建进程、连接数据库的时间可以通过池处理来节省。所以一般情况下速度可能会比直接连接数据库还要快一些。
 
我也遇到了该问题,在客户端点击了ApplyUpdate(0)三次后,应用服务器程序就死机了,我是照李维老师的那本系统篇的例子做的。
服务器端:有一个窗口,上面有一个DBGRID,是显示客户端传过来的要更新的数据,当客户端点击applyUpdate(0)三次后,这个表DBGRID就不会显示了,发生死机。
DBGRID的ClientDataset1的数据是直接在Provider的onUpdateData事件赋值的。
procedure TMySevenMultiSrv.sgUpdateSQLProviderUpdateData(Sender: TObject;
DataSet: TCustomClientDataSet);
var
iCount1,iCount2:integer;
begin
Form1.ClientDataSet1.Data:=DataSet.Data;
...
end;
按F8单步执行时,代码都是正常执行,但就是在窗口显示中,DBGRID会发生死机。真是弄不明白。
程序源代码如下:
---Server.pas
unit Server;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, DBClient, Grids, DBCtrls, DBGrids, ExtCtrls, ComCtrls;
type
TForm1 = class(TForm)
Panel1: TPanel;
Panel2: TPanel;
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
StringGrid1: TStringGrid;
ClientDataSet1: TClientDataSet;
DataSource1: TDataSource;
StatusBar1: TStatusBar;
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
end.

--ServerDM.pas
unit ServerDM;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
Windows, Messages, SysUtils, Classes, ComServ, ComObj, VCLCom, DataBkr,
DBClient, ServerApp_TLB, StdVcl, Provider, DB, ADODB;
type
TMySevenMultiSrv = class(TRemoteDataModule, IMySevenMultiSrv)
ADOConnection1: TADOConnection;
ADOQuery1: TADOQuery;
sgUpdateSQLProvider: TDataSetProvider;
sgUpdateDataSetProvider: TDataSetProvider;
ADOQuery2: TADOQuery;
procedure ADOQuery2BeforePost(DataSet: TDataSet);
procedure ADOQuery2AfterPost(DataSet: TDataSet);
procedure sgUpdateSQLProviderUpdateData(Sender: TObject;
DataSet: TCustomClientDataSet);
private
{ Private declarations }
protected
class procedure UpdateRegistry(Register: Boolean;
const ClassID, ProgID: string);
override;
public
{ Public declarations }
end;

implementation
uses Server;
{$R *.DFM}
procedure TMySevenMultiSrv.ADOQuery2AfterPost(DataSet: TDataSet);
begin
Form1.StatusBar1.Panels[0].Text:='After Post被触发了!';
end;

procedure TMySevenMultiSrv.ADOQuery2BeforePost(DataSet: TDataSet);
begin
Form1.StatusBar1.Panels[1].Text:='Before Post被触发了!';
end;

procedure TMySevenMultiSrv.sgUpdateSQLProviderUpdateData(Sender: TObject;
DataSet: TCustomClientDataSet);
var
iCount1,iCount2:integer;
begin
Form1.ClientDataSet1.Active:=false;
Form1.ClientDataSet1.Data:=DataSet.Data;
Form1.ClientDataSet1.Active:=True;
Form1.StringGrid1.ColCount:=0;
Form1.StringGrid1.RowCount:=0;
Form1.StringGrid1.ColCount:=Dataset.FieldCount;
Form1.StringGrid1.RowCount:=Dataset.RecordCount;
for icount1 := 0 to Dataset.FieldCount - 1do
Form1.StringGrid1.Cells[iCount1,0]:=Dataset.Fields[iCount1].FieldName;
for iCount1 := 0 to Dataset.RecordCount-1do
begin
for iCount2 := 0 to DataSet.FieldCount - 1do
begin
if (pfInUpdate in DataSet.Fields[iCount2].ProviderFlags) then
Form1.StringGrid1.Cells[iCount2,iCount1+1]:=Form1.StringGrid1.Cells[iCount2,iCount1+1]+
' pfInUpdate';
if (pfInWhere in DataSet.Fields[iCount2].ProviderFlags) then
Form1.StringGrid1.Cells[iCount2,iCount1+1]:=Form1.StringGrid1.Cells[iCount2,iCount1+1]+
' pfInWhere';
if (pfInKey in Dataset.Fields[icount2].ProviderFlags) then
Form1.StringGrid1.Cells[iCount2,iCount1+1]:=Form1.StringGrid1.Cells[iCount2,iCount1+1]+
' pfInKey';
if (pfHidden in Dataset.Fields[iCount2].ProviderFlags) then
Form1.StringGrid1.Cells[iCount2,iCount1+1]:=Form1.StringGrid1.Cells[iCount2,iCount1+1]+
' pfHidden';
end;
end;
end;

class procedure TMySevenMultiSrv.UpdateRegistry(Register: Boolean;
const ClassID, ProgID: string);
begin
if Register then
begin
inherited UpdateRegistry(Register, ClassID, ProgID);
EnableSocketTransport(ClassID);
EnableWebTransport(ClassID);
RegisterPooled(ClassID,10,10,True);
end else
begin
DisableSocketTransport(ClassID);
DisableWebTransport(ClassID);
UnRegisterPooled(ClassID);
inherited UpdateRegistry(Register, ClassID, ProgID);
end;
end;

initialization
TComponentFactory.Create(ComServer, TMySevenMultiSrv,
Class_MySevenMultiSrv, ciMultiInstance, tmApartment);
end.

--客户端代码:
unit Client;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, DBCGrids, ExtCtrls, DBCtrls, Db, DBClient, MConnect, Mask;
type
TForm2 = class(TForm)
DCOMConnection1: TDCOMConnection;
ClientDataSet1: TClientDataSet;
DBNavigator1: TDBNavigator;
Button1: TButton;
Edit1: TEdit;
DBCtrlGrid1: TDBCtrlGrid;
Label1: TLabel;
DBEdit1: TDBEdit;
DataSource1: TDataSource;
Label2: TLabel;
DBEdit2: TDBEdit;
Label3: TLabel;
DBEdit3: TDBEdit;
Label4: TLabel;
DBEdit4: TDBEdit;
Label5: TLabel;
DBEdit5: TDBEdit;
Label6: TLabel;
DBEdit6: TDBEdit;
Label7: TLabel;
DBEdit7: TDBEdit;
Label8: TLabel;
DBEdit8: TDBEdit;
Label9: TLabel;
DBEdit9: TDBEdit;
Label10: TLabel;
DBEdit10: TDBEdit;
Label11: TLabel;
DBEdit11: TDBEdit;
Button2: TButton;
ClientDataSet2: TClientDataSet;
Edit2: TEdit;
Button3: TButton;
ClientDataSet1customerID: TWideStringField;
ClientDataSet1CompanyName: TWideStringField;
ClientDataSet1contactName: TWideStringField;
ClientDataSet1ContactTitle: TWideStringField;
ClientDataSet1Address: TWideStringField;
ClientDataSet1City: TWideStringField;
ClientDataSet1Region: TWideStringField;
ClientDataSet1Postalcode: TWideStringField;
ClientDataSet1Country: TWideStringField;
ClientDataSet1phone: TWideStringField;
ClientDataSet1fax: TWideStringField;
procedure ClientDataSet1AfterPost(DataSet: TDataSet);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure ClientDataSet2AfterPost(DataSet: TDataSet);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;
implementation
{$R *.DFM}
procedure TForm2.ClientDataSet1AfterPost(DataSet: TDataSet);
begin
Edit1.Text := IntToStr(ClientDataSet1.ChangeCount);
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
ClientDataSet1.ApplyUpdates(0);
ClientDataSet1.Refresh;
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
ClientDataSet2.ApplyUpdates(0);
// ClientDataSet2.Refresh;
end;

procedure TForm2.ClientDataSet2AfterPost(DataSet: TDataSet);
begin
Edit2.Text := IntToStr(ClientDataSet2.ChangeCount);
end;

procedure TForm2.Button3Click(Sender: TObject);
begin
if DataSource1.DataSet = ClientDataSet1 then
DataSource1.DataSet := ClientDataSet2
else
DataSource1.DataSet := ClientDataSet1;
end;

end.
 
请问有状态连接是不是指在程序打开时就把SockedConnection.Connected设为true,程序退出时才关闭,状态连接是不是指每次查询数据时都要将SockedConnection.Connected设为true,查完后再设为False?谢谢!!
请问连接池是怎么建立的?谢谢!!!!!!
 
如果是用SocketConnection ,那么Scksrv.exe不能设为服务启动模式,应以程序运行方式启动!
 
其实应该在服务器端来进行对数据库的操作才是正道!
尽量少用或不用CLIENTDATASET来直接下达SQL指令。必须要用的时候也要尽早释放链接。
 
三层死机一般有几种原因:
一、服务器的中间层没写好
二、如果在多cpu的服务器中用了scktsrvr.exe,需要注意scktsrvr.exe的版本
看看我们的例子吧www.szmax.net/webpush-8.htm
 
COM+查询到数据后,使用Variant回传给ClientDataSet,然后关闭查询。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部