Len dopĺňam, že transakcia sa môže spustiť len jediný raz. Na to som zabudol, a dalo mi to poriadne zabrať.
Ano. Transakce je unikatni instance objektu ohranicujici davku prikazu v DBMS. A jako takova muze byt spustena (resp. vytvorena) jen jednou. Pomoci transakcniho objektu FireDAC (
TFDTransaction) muzes vytvaret transakce opakovane, ale pujde vzdy o unikatni instance (tudiz z pohledu dat GTT definovane s
ON COMMIT DELETE ROWS o separatni kontejner). Pokud ovsem nepujde o transakci vnorenou (vnorena transakce bude mit pristup k datum GTT, jedna-li se o stejny transakcni objekt FireDAC), tzn. v nasledujicim pripade lze sdilet data GTT mezi dvema query objekty:
FDQuery1.Transaction := FDTransaction1; // ← stejny transakcni objekt prirazen dvema ruznym query objektum
FDQuery2.Transaction := FDTransaction1; // ← stejny transakcni objekt prirazen dvema ruznym query objektum
FDQuery1.Transaction.StartTransaction; // ← start vnejsi transakce
try
FDQuery1.SQL.Text := 'INSERT INTO MyTempTable (TheInteger) VALUES (123)';
FDQuery1.ExecSQL;
FDQuery2.Transaction.StartTransaction; // ← start vnorene transakce
try
FDQuery2.SQL.Text := 'SELECT TheInteger FROM MyTempTable';
FDQuery2.Open;
Assert(FDQuery2.FieldByName('TheInteger').AsInteger = 123, 'GTT read failed!'); // data lze precist
FDQuery2.Transaction.Commit;
except
FDQuery2.Transaction.Rollback;
raise;
end;
FDQuery1.Transaction.Commit;
except
FDQuery1.Transaction.Rollback;
raise;
end;
Zatimco v pripade pouziti ruznych transakcnich objektu ne:
FDQuery1.Transaction := FDTransaction1; // ← tento query objekt ma svuj vlastni transakcni objekt
FDQuery2.Transaction := FDTransaction2; // ← tento query objekt ma svuj vlastni transakcni objekt
FDQuery1.Transaction.StartTransaction; // ← start transakce
try
FDQuery1.SQL.Text := 'INSERT INTO MyTempTable (TheInteger) VALUES (123)';
FDQuery1.ExecSQL;
FDQuery2.Transaction.StartTransaction; // ← start transakce
try
FDQuery2.SQL.Text := 'SELECT TheInteger FROM MyTempTable';
FDQuery2.Open;
Assert(FDQuery2.FieldByName('TheInteger').AsInteger = 123, 'GTT read failed!'); // data nelze precist
FDQuery2.Transaction.Commit;
except
FDQuery2.Transaction.Rollback;
raise;
end;
FDQuery1.Transaction.Commit;
except
FDQuery1.Transaction.Rollback;
raise;
end;