BUG: (and fix) TransactionManager is not created when "hard_commit" is defined in Firebird
Posted: 02.10.2019, 17:32
Hi, I updated to SVN revision 5967.
PROBLEM:
See //*** XXX *** commented lines.
ZDbcInterbase6.pas:
Tracking the callstack I found that FTransactionManager is created after:
ZDbcConnection.pas:
I use Delphi 7 and I access to Zeos through mORMot.
Best regards.
FIX:
ZDbcInterbase6.pas:
PROBLEM:
See //*** XXX *** commented lines.
ZDbcInterbase6.pas:
Code: Select all
procedure TZInterbase6Connection.OnPropertiesChange(Sender: TObject);
var
AC,RO: Boolean;
TIL: TZTransactIsolationLevel;
begin
if StrToBoolEx(Info.Values['hard_commit']) <> FHardCommit then begin
FTransactionManager.GetActiveTransaction.CloseTransaction; //*** EXCEPTION IS RAISED HERE, FTransactionManager is not initialized or created ***
FHardCommit := StrToBoolEx(Info.Values['hard_commit']);
end;
for AC := false to true do
for RO := false to true do
for til := low(TZTransactIsolationLevel) to high(TZTransactIsolationLevel) do begin
FTPBs[AC][RO][TIL] := '';
FTEBs[AC][RO][TIL].tpb_length := 0;
FTEBs[AC][RO][TIL].tpb_address := nil;
end;
end;
ZDbcConnection.pas:
Code: Select all
constructor TZAbstractConnection.Create(const ZUrl: TZURL);
begin
FClosed := True;
FDisposeCodePage := False;
if not assigned(ZUrl) then
raise Exception.Create('ZUrl is not assigned!')
else
FURL := TZURL.Create();
FDriverManager := DriverManager; //just keep refcount high
FDriver := DriverManager.GetDriver(ZURL.URL);
FIZPlainDriver := FDriver.GetPlainDriver(ZUrl);
fRegisteredStatements := {$IFDEF TLIST_IS_DEPRECATED}TZSortedList{$ELSE}TList{$ENDIF}.Create;
FURL.OnPropertiesChange := OnPropertiesChange; //*** AND HERE IS ASSIGNED ***
FURL.URL := ZUrl.URL; //*** AND FIRED HERE ***
FClientCodePage := Info.Values['codepage'];
{CheckCharEncoding}
ConSettings := New(PZConSettings);
SetConSettingsFromInfo(Info);
CheckCharEncoding(FClientCodePage, True);
FAutoCommit := True;
FReadOnly := False; //EH: Changed! We definitelly did newer ever open a ReadOnly connection by default!
FTransactIsolationLevel := tiNone;
FUseMetadata := True;
// should be set BEFORE InternalCreate
ConSettings^.Protocol := {$IFDEF UNICODE}UnicodeStringToASCII7{$ENDIF}(FIZPlainDriver.GetProtocol);
ConSettings^.Database := ConSettings^.ConvFuncs.ZStringToRaw(FURL.Database, ConSettings^.CTRL_CP, ConSettings^.ClientCodePage^.CP);
ConSettings^.User := ConSettings^.ConvFuncs.ZStringToRaw(FURL.UserName, ConSettings^.CTRL_CP, ConSettings^.ClientCodePage^.CP);
FChunkSize := StrToIntDef(Info.Values['chunk_size'], 4096);
// now InternalCreate will work, since it will try to Open the connection
InternalCreate; //*** FTransactionManager is created HERE ***
{$IFDEF ZEOS_TEST_ONLY}
FTestMode := 0;
{$ENDIF}
end;
Best regards.
FIX:
ZDbcInterbase6.pas:
Code: Select all
procedure TZInterbase6Connection.OnPropertiesChange(Sender: TObject);
var
AC,RO: Boolean;
TIL: TZTransactIsolationLevel;
begin
if StrToBoolEx(Info.Values['hard_commit']) <> FHardCommit then begin
if Assigned(FTransactionManager) then //*** ADDED THIS CHECK ***
FTransactionManager.GetActiveTransaction.CloseTransaction;
FHardCommit := StrToBoolEx(Info.Values['hard_commit']);
end;
for AC := false to true do
for RO := false to true do
for til := low(TZTransactIsolationLevel) to high(TZTransactIsolationLevel) do begin
FTPBs[AC][RO][TIL] := '';
FTEBs[AC][RO][TIL].tpb_length := 0;
FTEBs[AC][RO][TIL].tpb_address := nil;
end;
end;