gpt4 book ai didi

delphi - 连接失败时 DBXPool 会损坏内存

转载 作者:行者123 更新时间:2023-12-03 02:44:00 29 4
gpt4 key购买 nike

DBXPool 用于 TSQLConnection 上的 DelegateConnection 时,如果在调用 TSQLConnection.Open< 时 SQLServer 不可用 方法,第一次会超时。但如果您随后再次调用Open,它就会出现错误。在我的生产服务中,它在没有任何警告的情况下终止了进程——没有引发任何异常,什么也没有。该过程就这样消失了...在我创建的一个用于测试 DBXPool 的简单应用程序中,它认为 TSQLConnection 已连接,即使它没有连接。

是否有人在使用 DBXPool 作为 DelegateConnection 时遇到了麻烦,可以提供任何建议?

谢谢!

<<< 7/23 编辑 #2 >>>

我使用下面编辑 #1 中的代码来跟踪 DBX 框架。仅当使用DBXPool时才会调用以下方法:

(单位 DBXDelegate)

procedure TDBXDelegateConnection.Open;
begin
if not FConnection.IsOpen then
begin
TDBXAccessorConnection(FConnection).Open;
end;
end;

...它调用以下方法,无论是否使用 DBXPool 都会调用该方法:

(单位 DBXCommon)

procedure TDBXConnection.Open;
begin
// mark the state open so memory can be deallocated
// even if derived open or meta query fail
FOpen := true;

DerivedOpen;
DatabaseMetaData;
end;

注意评论。当发生异常时(例如,用户名错误或超时等),只有在不使用DBXPool的情况下才会调用以下代码。

(单位 DBXCommon)

procedure TDBXConnection.Close;
begin
CloseAllCommands;
RollbackAllTransactions;
DerivedClose;
SetTraceInfoEvent(nil);
FreeAndNil(FDatabaseMetaData);
FOpen := false;
end;

因为使用 DBXPool 时 FOpen 不会设置回 False,因此会导致下次 DerivedOpen 时执行不应该执行的代码code> 被调用,这会导致 AccessViolation 和内存损坏。有时 RTL 会捕获它,有时则不会(例如,我的生产服务被 Windows 终止)。我还无法更深入地跟踪 DBXDelegate 来确定为什么它没有捕获异常并调用 TDBXConnection.Close

<<< 7/23 编辑 #1 >>>

根据 Ken 的建议,我附上了简单的示例应用程序。我的服务应用程序刚刚死掉了。此应用程序在 dbxmss.dll 中显示访问冲突(今天)。昨天,它在第二次单击时没有引发异常,它只是将“已连接”返回为 True。对我来说似乎是内存损坏......

在带有或不带有 SQLServer 的计算机上构建并运行应用程序。单击每个按钮几次。两者都会在第一次单击时返回错误。 “With DBXPool”会认为它从第二次单击开始就已连接。运气好的话,说不定还能看到AV。 “W/O DBXPool”按钮每次都会失败,这是正确的。

项目1.dpr

program Project1;

uses
Forms,
Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

Unit1.dfm

object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 301
ClientWidth = 562
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 40
Top = 8
Width = 75
Height = 25
Caption = 'With DBXPool'
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 40
Top = 39
Width = 75
Height = 25
Caption = 'W/O DBXPool'
TabOrder = 1
OnClick = Button2Click
end
object SQLConnection1: TSQLConnection
DriverName = 'MSSQL'
GetDriverFunc = 'getSQLDriverMSSQL'
LibraryName = 'dbxmss.dll'
LoginPrompt = False
Params.Strings = (
'DriverUnit=DBXMSSQL'

'DriverPackageLoader=TDBXDynalinkDriverLoader,DBXCommonDriver150.' +
'bpl'

'DriverAssemblyLoader=Borland.Data.TDBXDynalinkDriverLoader,Borla' +
'nd.Data.DbxCommonDriver,Version=15.0.0.0,Culture=neutral,PublicK' +
'eyToken=91d62ebb5b0d1b1b'

'MetaDataPackageLoader=TDBXMsSqlMetaDataCommandFactory,DbxMSSQLDr' +
'iver150.bpl'

'MetaDataAssemblyLoader=Borland.Data.TDBXMsSqlMetaDataCommandFact' +
'ory,Borland.Data.DbxMSSQLDriver,Version=15.0.0.0,Culture=neutral' +
',PublicKeyToken=91d62ebb5b0d1b1b'
'GetDriverFunc=getSQLDriverMSSQL'
'LibraryName=dbxmss.dll'
'VendorLib=sqlncli10.dll'
'MaxBlobSize=-1'
'OSAuthentication=False'
'PrepareSQL=True'
'ErrorResourceFile='
'drivername=MSSQL'
'schemaoverride=%.dbo'
'HostName=127.0.0.1'
'Database=database'
'User_Name=username'
'Password=password'
'blobsize=-1'
'localecode=0000'
'isolationlevel=ReadCommitted'
'os authentication=False'
'prepare sql=False'
'DelegateConnection=DBXPool'
'DBXPool.MaxConnections=20'
'DBXPool.MinConnections=1'
'DBXPool.ConnectTimeout=1000'
'DBXPool.DriverUnit=DBXPool'
'DBXPool.DelegateDriver=True'
'DBXPool.DBXPool.MaxConnections=20'
'DBXPool.DBXPool.MinConnections=1'
'DBXPool.DBXPool.ConnectTimeout=1000'
'DBXPool.DBXPool.DriverUnit=DBXPool'
'DBXPool.DBXPool.DelegateDriver=True'
'DBXPool.DBXPool.DriverName=DBXPool'
'DBXPool.DriverName=DBXPool')
VendorLib = 'sqlncli10.dll'
Left = 8
Top = 8
end
object SQLConnection2: TSQLConnection
DriverName = 'MSSQL'
GetDriverFunc = 'getSQLDriverMSSQL'
LibraryName = 'dbxmss.dll'
LoginPrompt = False
Params.Strings = (
'DriverUnit=DBXMSSQL'

'DriverPackageLoader=TDBXDynalinkDriverLoader,DBXCommonDriver150.' +
'bpl'

'DriverAssemblyLoader=Borland.Data.TDBXDynalinkDriverLoader,Borla' +
'nd.Data.DbxCommonDriver,Version=15.0.0.0,Culture=neutral,PublicK' +
'eyToken=91d62ebb5b0d1b1b'

'MetaDataPackageLoader=TDBXMsSqlMetaDataCommandFactory,DbxMSSQLDr' +
'iver150.bpl'

'MetaDataAssemblyLoader=Borland.Data.TDBXMsSqlMetaDataCommandFact' +
'ory,Borland.Data.DbxMSSQLDriver,Version=15.0.0.0,Culture=neutral' +
',PublicKeyToken=91d62ebb5b0d1b1b'
'GetDriverFunc=getSQLDriverMSSQL'
'LibraryName=dbxmss.dll'
'VendorLib=sqlncli10.dll'
'MaxBlobSize=-1'
'OSAuthentication=False'
'PrepareSQL=True'
'ErrorResourceFile='
'drivername=MSSQL'
'schemaoverride=%.dbo'
'HostName=127.0.0.1'
'Database=database'
'User_Name=username'
'Password=password'
'blobsize=-1'
'localecode=0000'
'isolationlevel=ReadCommitted'
'os authentication=False'
'prepare sql=False')
VendorLib = 'sqlncli10.dll'
Left = 8
Top = 39
end
end

Unit1.pas

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DBXMSSQL, StdCtrls, DB, SqlExpr, DBXPool;

type
TForm1 = class(TForm)
Button1: TButton;
SQLConnection1: TSQLConnection;
SQLConnection2: TSQLConnection;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses
DBXCommon;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
SQLConnection1.Close;
SQLConnection1.Open;
if SQLConnection1.Connected then
MessageDlg('connected connection 1', mtInformation, [mbOK], 0);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
SQLConnection2.Close;
SQLConnection2.Open;
if SQLConnection2.Connected then
MessageDlg('connected connection 2', mtInformation, [mbOK], 0);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
// for testing purposes, shorten the timeout so that the timeout occurs quickly
SQLConnection1.Params.Values[TDBXPropertyNames.ConnectTimeout] := '1';
SQLConnection2.Params.Values[TDBXPropertyNames.ConnectTimeout] := '1';
end;

end.

最佳答案

Embarcadero 支持今天通知我,此问题已得到解决,并将在下一个常规版本(例如 XE2)中提供。

关于delphi - 连接失败时 DBXPool 会损坏内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6783715/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com