Browse Source

* Fix AV when freeing transactions. Reported by Pascal Riekenberg. Fixes issuu #40571

Michaël Van Canneyt 1 year ago
parent
commit
3b7d6d21e2
2 changed files with 19 additions and 12 deletions
  1. 9 10
      packages/fcl-db/src/base/database.inc
  2. 10 2
      packages/fcl-db/src/sqldb/sqldb.pp

+ 9 - 10
packages/fcl-db/src/base/database.inc

@@ -454,15 +454,14 @@ end;
 procedure TDBTransaction.SetDatabase(Value: TDatabase);
 
 begin
-  If Value<>FDatabase then
-    begin
-    CheckInactive;
-    If Assigned(FDatabase) then
-      FDatabase.UnregisterTransaction(Self);
-    If Value<>Nil Then
-      Value.RegisterTransaction(Self);
-    FDatabase:=Value;
-    end;
+  If Value=FDatabase then
+    exit;
+  CheckInactive;
+  If Assigned(FDatabase) then
+    FDatabase.UnregisterTransaction(Self);
+  If Value<>Nil Then
+    Value.RegisterTransaction(Self);
+  FDatabase:=Value;
 end;
 
 constructor TDBTransaction.Create(AOwner: TComponent);
@@ -523,9 +522,9 @@ end;
 destructor TDBTransaction.Destroy;
 
 begin
-  Database:=Nil;
   CloseDataSets;
   RemoveDatasets;
+  Database:=Nil;
   FDatasets.Free;
   Inherited;
 end;

+ 10 - 2
packages/fcl-db/src/sqldb/sqldb.pp

@@ -2518,13 +2518,21 @@ Const
 
 var
   Q : TSQLQuery;
+  C : TSQLConnection;
 
 begin
   Q:=DS as TSQLQuery;
   if not (sqoKeepOpenOnCommit in Q.Options) then
     inherited CloseDataset(Q,InCommit);
-  if UnPrepOptions[InCommit] in SQLConnection.ConnOptions then
-   Q.UnPrepare;
+  C:=SQLConnection;
+  if C=Nil then
+    C:=Q.SQLConnection;
+  if Q.Prepared then
+    if not Assigned(C) then
+      // No database, we must unprepare...
+      Q.UnPrepare // Unprepare checks if there is still a cursor.
+    else if UnPrepOptions[InCommit] in C.ConnOptions then
+      Q.UnPrepare;
 end;
 
 procedure TSQLTransaction.Commit;