Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   .NET-Sprachen (https://www.delphipraxis.net/82-net-sprachen/)
-   -   C# Firebird - Mehrere abhängige SQLs in einer Transaktion (https://www.delphipraxis.net/188032-firebird-mehrere-abhaengige-sqls-einer-transaktion.html)

Neutral General 25. Jan 2016 16:17

Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Hallo,

Ich verzweifel hier langsam :(
Ich möchte eine Liste von SQL-Befehlen hintereinander in der gleichen Transaktion ausführen.
Wenn ich allerdings ein CREATE TABLE ausführe (erfolgreich) und danach ein INSERT in diese Tabelle machen will,
schlägt das INSERT fehl weil die vorher erstellte Tabelle angeblich nicht existiert:

Code:
FbTransaction trans = connection.BeginTransaction(); // connection ist eine aktive Verbindung
try
{
  for (int i=0; i < SqlStatements.Count; i++) // List<string> SqlStatements
  {
    FbCommand cmd = new FbCommand(SqlStatements[i], connection, trans);
    cmd.ExecuteNonQuery();
  }

  trans.Commit();
}
catch(FbException ex)
{
  trans.Rollback();
}

Kann mir jemand sagen was ich falsch mache?

(PS: Ich weiß, dass es FbBatchExecution gibt, aber das reicht für meine Zwecke nicht, ich muss es von Hand machen)

Crosspost: http://www.entwickler-ecke.de/viewtopic.php?p=698278#

jobo 25. Jan 2016 16:24

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Ich kenne Firebird am ehesten von ein paar Tests mit Flamerobbin.
Muss man da nicht nach einem Create Table auch commiten? Ich weiß es nicht genau auswendig.

Aber DML und DDL werden von verschiedenen Systemen ganz unterschiedlich gehandhabt.

Ein DDL (z.B.) create table macht in Oracle bspw. implizit ein commit.
Letztlich ist es ja auch so, dass in der DB selbst, also im eigenen Dictionary die Tabellen, Spalten, etc. pp eingetragen werden (müssen). Das geschieht bei Oracle zwar mit autonomen TR, aber trotzdem wird zuvor datentechnisch reiner Tisch gemacht.

Also evtl. musst Du alle DDL zu Anfang mit commit durchführen. Falls FB Zwischenschritte unterstützt, kannst Du Dir das vielleicht zunutze machen und bei einem Fehler trotzdem bis zum allerersten Anfang zurückrollen.

nahpets 25. Jan 2016 16:25

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Schau mal hier: http://entwickler-forum.de/showthrea...d-Transactions

oder hier: http://stackoverflow.com/questions/1...-a-transaction

Kurz: Demnach geht nicht in einer Transaktion.

Neutral General 25. Jan 2016 16:34

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Zitat:

Zitat von nahpets (Beitrag 1328157)
Schau mal hier: http://entwickler-forum.de/showthrea...d-Transactions

oder hier: http://stackoverflow.com/questions/1...-a-transaction

Kurz: Demnach geht nicht in einer Transaktion.

Den zweiten Link hab ich auch grad gefunden.
Und was machen ich dann wenn ich ein Skript ausführen möchte (möglicherweise lange Skripte in denen Tabellen erstellt, gedroppt, Daten gelöscht und eingefügt werden)
und bei einem Fehler das Skript zurückrollen will? Das muss doch auf irgendeine Weise möglich sein

jobo 25. Jan 2016 16:40

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Bei DDL musst Du traditionell die Erzeugung von Objekten, Änderung, Löschun eher selbst verwalten.

Du könntest versuchen mit Execute Statement <stmt >with autonomous transaction..
falls das geht, kommst Du durch, falls kein Fehler auftritt, wenn das DDL Fehler wirft, bist Du aber auch nicht viel weiter.

p80286 25. Jan 2016 16:50

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Zitat:

Zitat von Neutral General (Beitrag 1328163)
Und was machen ich dann wenn ich ein Skript ausführen möchte (möglicherweise lange Skripte in denen Tabellen erstellt, gedroppt, Daten gelöscht und eingefügt werden)
und bei einem Fehler das Skript zurückrollen will? Das muss doch auf irgendeine Weise möglich sein

umdenken. und aus einem Script mehrere machen, wo Du im Fehlerfall zu Fuß wieder aufräumst/ aufräumen kannst.
(Wenn FB alles das könnte was die "großen" können, welche Daseinsberechtigung hätten die dann noch?)


Gruß
K-H

Neutral General 25. Jan 2016 16:51

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Mir kam grad eine böse Idee die ich aber bisher (vielleicht zum Glück?) nicht zum Laufen gebracht habe.
Vielleicht kann ich ja die Delta files misbrauchen?

Code:
alter database begin backup;

-- skript mit commmit nach jedem Befehl

alter database end backup;
Falls dort dann zwischendrin was schief läuft könnte ich ja irgendwie vielleicht die delta Datei löschen und so mein Skript quasi zurückrollen? :stupid: :duck:

nahpets 25. Jan 2016 16:53

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Also versuchen wir das mit "irgendwie möglich" mal locker zu sehen ;-)

1. Script: alles, was mit DDL zu tuen hat. (eine Transaktion)
2. Script: alles, was mit DML zu tuen hat. (eine Transaktion)
3. Script: alles, was im Fehlerfalle erforderlich ist. (eine Transaktion)

Das erste Script wird ausgeführt, tritt ein Fehler auf, sollte ein Rollback ausreichen und Abbruch der Routine.
Fehlerlos durchgelaufen: Commit, zweites Script ausführen.
Zweites Script fehlerfrei: Commit und Ende der Routine.
Zweites Script Fehler aufgetreten: Rollback und drittes Script ausführen.

Im dritten Script muß restlos alles, was im ersten Script gemacht wurde, wieder aus der Datenbank entfernt werden.
Für jedes Create Table ein entsprechendes Drop Table...

Was ist, wenn im dritten Script Fehler auftreten?
Sch..., keine sinnvolle Idee im "Schnellzugriff" vorhanden :-(
Und genau dass wird der größte Teil der anstehenden Arbeit werden. Fehlerresistente Fehlerbeseitigung.

Dazu Frage:

Läuft das im laufenden Betrieb oder hast Du die Datenbank da in alleinigem Vollzugriff?

Wenn Du der "Alleinherrscher" über die Aufgabe bist:

0. Script: Backup der Datenbank erstellen.
1. Script: Wie oben...
2. Script: Wie oben...
3. Script: Restore der Datenbank aus obigem Backup.

Neutral General 25. Jan 2016 18:06

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Zitat:

Zitat von nahpets (Beitrag 1328169)
Läuft das im laufenden Betrieb oder hast Du die Datenbank da in alleinigem Vollzugriff?

Wenn Du der "Alleinherrscher" über die Aufgabe bist:

0. Script: Backup der Datenbank erstellen.
1. Script: Wie oben...
2. Script: Wie oben...
3. Script: Restore der Datenbank aus obigem Backup.

Ja ich habe alleinigen Vollzugriff.
Die Sache ist nur die: Ich will nicht bei 20 Skripten 20x eine > 1GB Datenbank sichern und wiederherstellen.
Das dauert dann statt 1 Minute 1 Stunde.

Die Lösung mit dem Rollback-Skript gefällt mir auch nicht sonderlich. Da muss ich alle Skripte ja fast doppelt schreiben :?

Gibt es nicht tatsächlich eine Möglichkeit das Ganze über Delta Files, bzw. inkrementelle Backups zu lösen? die ich dann zurückspielen, bzw. reverten kann? (Das wären dann ja meistens nur wenige KB)

nahpets 25. Jan 2016 18:18

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Wäre "Datenbanksicherung für Arme" 'ne Alternative?

Datenbankserver runterfahren.
Datenbankdatei per Copy irgendwohin kopieren.
Datenbankserver starten.
Script laufen lassen.
Kopie der Datenbankdatei löschen.

Im Fehlerfalle:
Datenbankserver stoppen.
Originaldatenbankdatei löschen.
Kopie an Stelle der Originaldatenbankdatei.
Datenbankserver starten.

'ne andere Möglichkeit kenn' ich nicht, aber das heißt selbstverfreilich nicht, dass es da nicht doch was besseres geben könnte.

bepe 25. Jan 2016 18:26

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Nie benutzt aber das klingt als suchst du nach SavePoints.

Perlsau 25. Jan 2016 18:54

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Um eine Firebird-Datenbank-Datei zu sichern, legt man gewöhnlich ein Backup mit dem Firebird-Utility GBak an. Dazu muß man weder den Server herunterfahren noch Clients abmelden. Auch für das Restore muß der Server nicht heruntergefahren werden, Clients dürfen währenddessen aber keine mit der Datenbank verbunden sein.

Für das gewöhnliche Kopieren der Datenbank-Datei gilt dasselbe wie für das Restore via GBak: Datenbankserver kann laufen, aber Clients dürfen keine verbunden sein. Dasselbe gilt dann natürlich auch für das gewöhnliche Zurück-Kopieren.

Irgendwo in den Weiten der DP-Threads hatte mir einst ein ausgewiesener Fachmann (entweder Thomas "FB-Evangelist" Steinmaurer oder Holger "IbExpert" Klemt würde ich tippen) den guten, aber kostenlosen Rat erteilt, auf das Kopieren einer Firebird-DB-Datei innerhalb einer Anwendung, die diese Datei nutzt, möglichst zu verzichten, weil nach einem Disconnect womöglich noch eine kurze Zeit irgendwelche Sachen vom Firebird-Server erledigt werden. Bei der Embedded-Variante wäre das vermutlich egal, obwohl hier seit Version 2.5 oder so auch bei Embedded mehrere User auf dieselbe DB-Datei zugreifen können, allerdings mit gewissen Einschränkungen, aber das ist ein anderes Thema.

Und da Firebird komplett kostenlos ist, gibt's auch kein "Backup für Arme" :-D

nahpets 25. Jan 2016 19:14

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
@Perlsau

Beim "Backup für Arme" meinte ich das nicht im monetären Sinne, sondern in dem der "ärmlichen" Professionalität meines Vorschlages, um an einem Problem vorbei zu kommen, für das ich keine professionelle Lösung weiß. ;-)

Dejan Vu 26. Jan 2016 07:08

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Vielleicht ist der Umstieg von SQL-Server auf FB doch keine so gute Idee.
Ich würde an Deiner/eurer Stelle analysieren, ob es noch weitere Fallstricke gibt (oder ist die Frage/das Problem Bestandteil einer Machbarkeitsstudie?).

Neutral General 26. Jan 2016 07:31

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Zitat:

Zitat von Dejan Vu (Beitrag 1328229)
Vielleicht ist der Umstieg von SQL-Server auf FB doch keine so gute Idee.
Ich würde an Deiner/eurer Stelle analysieren, ob es noch weitere Fallstricke gibt (oder ist die Frage/das Problem Bestandteil einer Machbarkeitsstudie?).

Habe nie etwas von einem Umstieg geredet :gruebel:
Wir haben schon immer Firebird benutzt.

Zitat:

Zitat von bepe (Beitrag 1328181)
Nie benutzt aber das klingt als suchst du nach SavePoints.

Dachte ich auch für einen Moment, aber die funktionieren halt nur innerhalb einer Transaktion. Sobald ich commite kann ich nicht mehr zurückspringen und nach einem CREATE TABLE muss ich ja scheinbar committen.

Zitat:

Zitat von nahpets (Beitrag 1328180)
Wäre "Datenbanksicherung für Arme" 'ne Alternative?

Zitat:

Zitat von Perlsau (Beitrag 1328183)
Um eine Firebird-Datenbank-Datei zu sichern, legt man gewöhnlich ein Backup mit dem Firebird-Utility GBak an.

Ich kenne gbak ;) Aber da ich ein Datenbank-Updateverfahren entwickle wo auch mal einige Skripte hintereinander ausgeführt werden ist ein (komplettes) Backup(/Restore) (egal ob arm oder reich) zu viel overhead. Die Ausführungsdauer der meisten Skripte liegt bei unter 1 Sekunde. Für jedes Skript vorher ein Backup einer > 1GB Datenbank anzulegen sprengt das Ganze leider :(

jobo 26. Jan 2016 08:07

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Zitat:

Zitat von Neutral General (Beitrag 1328233)
Aber da ich ein Datenbank-Updateverfahren entwickle wo auch mal einige Skripte hintereinander ausgeführt werden ist ein (komplettes) Backup(/Restore) (egal ob arm oder reich) zu viel overhead.

Das Thema ist wie Du siehst nicht tivial. Ein Grund für die Existenz von Backups ist ja die Möglichkeit, sich gegen fehlerhafte Updates abzusichern.
Wahrscheinlich musst Du Deine Strategie überdenken.

haentschman 26. Jan 2016 08:10

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Liste der Anhänge anzeigen (Anzahl: 2)
Moin...:P
Zitat:

CREATE TABLE muss ich ja scheinbar committen.
...:gruebel: Entweder habe ich das mißverstanden oder was übersehen. Du bemängelst das in einem Script kein Datenbankerzeugen und Tabellen Erstellen stattfinden kann. (Firebird)... Einspruch euer Ehren. :P
Script auf das wesentliche gekürzt:
Code:
SET SQL DIALECT 3;

SET NAMES NONE;

SET CLIENTLIB 'C:\Program Files\Firebird\Firebird25\DLL32\fbclient.dll';

CREATE DATABASE 'firma-server /3025:D:\tmp\Bla.FDB'
USER 'SYSDBA' PASSWORD 'masterkey'
PAGE_SIZE 16384
DEFAULT CHARACTER SET NONE COLLATION NONE;



/******************************************************************************/
/****                               Domains                               ****/
/******************************************************************************/

CREATE DOMAIN ID AS
INTEGER
NOT NULL;

CREATE DOMAIN STRING30 AS
VARCHAR(30)
NOT NULL;

/******************************************************************************/
/****                              Generators                             ****/
/******************************************************************************/

CREATE GENERATOR ID_GEN;
SET GENERATOR ID_GEN TO 99;

/******************************************************************************/
/****                                Tables                               ****/
/******************************************************************************/

CREATE TABLE T_MASTER_DEVICE_TYPES (
    ID                   ID,
    F_DEVICE_TYPE_ID     ID,
    F_DEVICE_TYPE_STRING STRING30
);

INSERT INTO T_MASTER_DEVICE_TYPES (ID, F_DEVICE_TYPE_ID, F_DEVICE_TYPE_STRING) VALUES (1, 0, 'Blübbchen');

COMMIT WORK;

/******************************************************************************/
/****                             Primary Keys                            ****/
/******************************************************************************/

ALTER TABLE T_MASTER_DEVICE_TYPES ADD CONSTRAINT PK_T_MASTER_DEVICE_TYPES_1 PRIMARY KEY (ID);

/******************************************************************************/
/****                               Indices                               ****/
/******************************************************************************/

/******************************************************************************/
/****                               Triggers                              ****/
/******************************************************************************/


SET TERM ^ ;



/******************************************************************************/
/****                         Triggers for tables                         ****/
/******************************************************************************/

/* Trigger: T_MASTER_DEVICE_TYPES_BI */
CREATE OR ALTER TRIGGER T_MASTER_DEVICE_TYPES_BI FOR T_MASTER_DEVICE_TYPES
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  if (new.id is null) then
    new.id = gen_id(id_gen,1);
end
^

SET TERM ; ^

COMMIT WORK;
Das ganze in eine Transaktion gepackt und gut... 8-)

mkinzler 26. Jan 2016 08:13

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Das COMMIT ist das Zauberwort. Wenn ich den TE richtig verstanden habe möchte er ja alles in einer Transaktion haben und das geht nicht.

haentschman 26. Jan 2016 08:23

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
:P Wie du aber siehst braucht es nach dem CREATE DATABASE kein COMMIT vor dem CREATE TABLE. Dann kann das Script doch in einer Transaktion laufen oder? Im Script wird nach den einzelnen Datentabellen commited weil ich das so eingestellt habe. Die Commits könntest du auch weglassen...insbesondere das letzte COMMIT weil das von außen durchgeführt wird.

Frage: Wir reden wirklich über Script (IBCScript) und nicht mehrere SQL Anweisungen (IBCQuery) nacheinander?

Neutral General 26. Jan 2016 08:25

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Zitat:

Zitat von haentschman (Beitrag 1328239)
Moin...:P
Zitat:

CREATE TABLE muss ich ja scheinbar committen.
...:gruebel: Entweder habe ich das mißverstanden oder was übersehen. Du bemängelst das in einem Script kein Datenbankerzeugen und Tabellen Erstellen stattfinden kann. (Firebird)... Einspruch euer Ehren. :P

Das ganze in eine Transaktion gepackt und gut... 8-)

Zitat:

Zitat von haentschman (Beitrag 1328243)
:P Wie du aber siehst braucht es nach dem CREATE DATABASE kein COMMIT vor dem CREATE TABLE. Dann kann das Script doch in einer Transaktion laufen oder? Im Script wird nach den einzelnen Datentabellen commited weil ich das so eingestellt habe. Die Commits könntest du auch weglassen...insbesondere das letzte COMMIT weil das von außen durchgeführt wird.

In IBExpert läuft sowas natürlich. Selbst ohne das commit work; zwischendurch, aber nur weil IBExpert (scheinbar) implizit an diesen Stellen committed.
Erstell mal in deinem eigenen Code eine Transaktion und versuch diese beiden Befehle hintereinander in dieser Transaktion auszuführen ohne zwischendurch zu committen:

1) CREATE TABLE DUMMY_TABLE(ID INTEGER, NAME VARCHAR(80))
2) INSERT INTO DUMMY_TABLE (ID, NAME) VALUES (1, 'Hans')

Probiers wirklich mal aus! Ich dachte genauso wie du bis gestern :mrgreen:

haentschman 26. Jan 2016 08:30

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Eben gesehen:
Zitat:

for (int i=0; i < SqlStatements.Count; i++) // List<string> SqlStatements
{
FbCommand cmd = new FbCommand(SqlStatements[i], connection, trans);
cmd.ExecuteNonQuery();
}
...die SQL Statements als Querys hintereinander und nicht als Script. Das sind 2 Paar Schuhe. In deinen DB Komponenten gibt es bestimmt eine Script Komponente. Der übergibst du das Script...fertsch.

Zitat:

In IBExpert läuft sowas natürlich. Selbst ohne das commit work; zwischendurch, aber nur weil IBExpert (scheinbar) implizit an diesen Stellen committed.
Erstell mal in deinem eigenen Code eine Transaktion und versuch diese beiden Befehle hintereinander in dieser Transaktion auszuführen ohne zwischendurch zu committen:
Falsch...:P Ich führe dieses Script auch in der Anwendung aus. Mit der Scriptkomponente und nicht als Querys.

Neutral General 26. Jan 2016 08:34

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Ohne 100%ig sicher zu sein: Aber was glaubst du was die Skriptkomponente sonst macht?

Dann versuch mal in der Skriptkomponente eine Tabelle zu erstellen, Daten einzufügen und danach provozier einen SQL fehler im 3. Befehl und dann machst du ein Rollback.
Ziemlich sicher dass die Tabelle trotzdem da sein wird

haentschman 26. Jan 2016 08:53

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Zitat:

Dann versuch mal in der Skriptkomponente eine Tabelle zu erstellen, Daten einzufügen und danach provozier einen SQL fehler im 3. Befehl und dann machst du ein Rollback.
Ziemlich sicher dass die Tabelle trotzdem da sein wir
:gruebel: Auch wenn eine Transaktion drumherum ist? ...muß ich echt nochmal bei Gelegenheit prüfen. Ich klinke mich dann mal aus bis ich es definitiv weiß. :zwinker:

Neutral General 26. Jan 2016 09:00

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Zitat:

Zitat von haentschman (Beitrag 1328258)
Zitat:

Dann versuch mal in der Skriptkomponente eine Tabelle zu erstellen, Daten einzufügen und danach provozier einen SQL fehler im 3. Befehl und dann machst du ein Rollback.
Ziemlich sicher dass die Tabelle trotzdem da sein wir
:gruebel: Auch wenn eine Transaktion drumherum ist?

Ja. Probiers bitte wirklich mal :)
Falls es DOCH klappt dann bin ich allerdings verwirrt und irgendwas stimmt hinten und vorne nicht.
Aber nach allem was ich seit gestern gelesen/gelernt habe dürfte das selbst mit Transaktion außenrum nicht funktionieren.

haentschman 26. Jan 2016 09:05

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Zitat:

Aber nach allem was ich seit gestern gelesen/gelernt habe dürfte das selbst mit Transaktion außenrum nicht funktionieren.
...ich lerne auch gern dazu. :P Bin grad am probieren. Es läßt mir keine Ruhe. Das würde auch mein Konzept auf den Kopf stellen...:roll:

I am not amused... :roll: Tatsächlich bleiben die Tabellen trotz Rollback zurück. Suuupiii! Ich muß auch das Konzept ändern.

Workaround:
Da es ja um die komplette Erzeugung der Datenbank geht, empfehle ich das Script in einem TRY / EXCEPT Block laufen zu lassen und im Fehlerfalle die erzeugte Datenbank, nach einem DISCONNECT zu löschen.

Neutral General 26. Jan 2016 10:50

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Zitat:

Zitat von haentschman (Beitrag 1328263)
I am not amused... :roll: Tatsächlich bleiben die Tabellen trotz Rollback zurück. Suuupiii! Ich muß auch das Konzept ändern.

Workaround:
Da es ja um die komplette Erzeugung der Datenbank geht, empfehle ich das Script in einem TRY / EXCEPT Block laufen zu lassen und im Fehlerfalle die erzeugte Datenbank, nach einem DISCONNECT zu löschen.

Willkommen im Club :D
Leider geht es bei mir NICHT um die komplette Erzeugung einer Datenbank sondern um das erweitern/updaten einer schon vorhandenen aktiven Kundendatenbank mit Daten.
Von daher funktioniert dein Workaround bei mir leider nicht :(

Lemmy 26. Jan 2016 11:16

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Zitat:

Zitat von Neutral General (Beitrag 1328279)
Leider geht es bei mir NICHT um die komplette Erzeugung einer Datenbank sondern um das erweitern/updaten einer schon vorhandenen aktiven Kundendatenbank mit Daten.

ähm...

nur mal so von Leidensgenosse zu Leidensgenosse:
Hat dein Arbeitgeber eine so gute Haftpflichtversicherung? Selbst ein triviales CREATE SEQUENCE ohne vorhergehende Datensicherung auf Kundendatenbanken los zu lassen ist... mir fehlen gerade die Worte...

Wenn ich beim Kunden am Rechner bin und selbst dann wenn mir der Kunde versichert, dass er gerade eben eine Datensicherung gemacht hat, der kann mir auch gerne die Datei zeigen, bevor ich auch nur ein Select * from rdb$Database absetze wird eine Datensicherung gemacht. Immer. Grundsätzlich. Und ganz speziell Freitag Nachmittag wenn ich eigentlich den Rechner runter fahren wollte und dann ruft der Kunde noch an :-(

Schon allein aus dem Grund um dem Kunden anschließend beweisen zu können, dass er den Fehler gebaut hat und nicht mein Select * from X an seinem Datenverlust schuld ist.


Und nein: Nicht alle Kunden sind so. Aber einer reicht.

Daher ist die einzig richtige Vorgehensweise:
1. Datensicherung durchführen
2. Datensicherung PRÜFEN! (d.h. in einem temp-Verzeichnis die Datenbank wieder herstellen - weil Firebird div. Fehler erst dann fest stellen kann, wenn er die Datenbank neu schreibt) Wenn Du die Datensicherung nicht restoren kannst, dann hast du keine Datensicherung!
3. Dann (und erst dann) Script einspielen (sicher dass Du den Punkt 2 der Liste nicht übersehen hast?)
Bei unseren Datenbanken (um die 400 MB) braucht das rund ne Minute, bei über 1 GByte je nach Server noch mal deutlich länger. Das ist nicht schön. Aber hast Du schon mal dran gedacht, wie lange es dauert die Daten noch mal einzugeben?

Grüße

Neutral General 26. Jan 2016 12:05

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Es werden regelmäßig automatische Backups der Kundendatenbank gemacht.
Das Problem ist nur, dass die Datenbank nach eine Skriptfehler in einem (mehr oder weniger) undefinierten Zustand ist,
den man im besten Fall durch das zurückspielen einer Datensicherung oder das manuelle korrigieren der Datenbank bzw. das manuelle Ausführen des restlichen Skripts beheben kann.

Jetzt bleibt wohl nichts anderes übrig als eine Datensicherung zurückzuspielen wenn was schief läuft aber falls es so funktioniert hätte wie ich dachte und man bedingungslos komplette Skripte zurückrollen könnte dann wäre ein Fehler in einem Skript deutlich harmloser und man müsste bloß den Fehler beheben und das Skript erneut ausführen. So war jedenfalls meine Vorstellung.

jobo 26. Jan 2016 13:02

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Wenn es so ist-Einzelfall-, dann brauchst Du ein Strukturbild (DDL Script) der Kundendb.
Daraufhin musst du gezielt ein (Reparatur)Skript anlegen. Also Reparatur der Struktur.
Alles was dann kommt, die Inhalte, da kannst Du nach Lust und Laune mit Transaktionen / Rollbacks arbeiten. Darauf ist das Konzept ja ausgelegt.

Falls Du ein universelles Update Programm erstellst, wirst Du sicher eine Menge Abnehmer dafür finden.

Dejan Vu 26. Jan 2016 14:04

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Pseudocode:
Code:
try
{
  foreach (IRevertableScript script in scripts)
  {
    ExecuteScript(script.SetupScript);
    revertable.Add(script);
  }
catch
{
  foreach (IRevertableScript scriptToUndo in revertable)
  {
     ExecuteScript(script.TeardownScript);
  }
}
Anstatt also einfach strings auszuführen, erstellst Du also pro 'Script' ein Objekt, bestehend aus zwei Skripten: Ein 'SetupScript' und ein 'TeardownScript', wobei das TeardownScript quasi die Umkehrfunktion des 'SetupScript' ist.
Also: Create Table => Drop Table etc.

Vermutlich muss man die Teardowns in umgekehrter Reihenfolge ausführen. Für einfache Sachen geht das und viele DB-Migratoren machen das auch so (z.B. der von EF)

Das Konzept an sich ist ja sprachenunabhängig.

Lemmy 26. Jan 2016 14:45

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Zitat:

Zitat von Neutral General (Beitrag 1328286)
Jetzt bleibt wohl nichts anderes übrig als eine Datensicherung zurückzuspielen wenn was schief läuft aber falls es so funktioniert hätte wie ich dachte und man bedingungslos komplette Skripte zurückrollen könnte dann wäre ein Fehler in einem Skript deutlich harmloser und man müsste bloß den Fehler beheben und das Skript erneut ausführen. So war jedenfalls meine Vorstellung.

Dann zerlege dein Script in kleine atomare Schritte:
1. Tabelle anlegen
2. Generator anlegen
3. Trigger anlegen
4. Daten einspielen
5. Update Bestandsdaten

bricht es an einer Stelle ab, dann hast Du eben keinen undefinierten Stand, da du genau nachvollziehen kannst an welcher Stelle das Script mit welcher Meldung abgeraucht ist (-> das stimmt natürlich bei umfangreichen UPDATE Statements nicht). Dann die Ursache korrigieren und die Scriptausführung fortsetzen - das macht dann idealerweise dein Updateprogramm, da es sich in einer Hilfstabelle merkt in welcher Version (sprich welches Script) und an welchem Schritt die letzte Ausführung stehen geblieben ist

frankyboy1974 26. Jan 2016 14:56

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
hallo,

ich möchte hier auch nochmal Folgendes in den Raum werfen. Vielleicht hilft es den Transaktionslevel der DB anders einzustellen. Ich hab jetzt nicht alle Beiträge auf dem Schirm, aber vielleicht hilft das irgendwie weiter Link. Wenn es nicht helfen sollte, trotzdem schön, dass wir darüber gesprochen haben. Ansonsten fand ich den Beitrag mit den Savepoints eigentlich ganz hilfreich.

mfg

Neutral General 26. Jan 2016 15:23

AW: Firebird - Mehrere abhängige SQLs in einer Transaktion
 
Zitat:

Zitat von frankyboy1974 (Beitrag 1328303)
hallo,

ich möchte hier auch nochmal Folgendes in den Raum werfen. Vielleicht hilft es den Transaktionslevel der DB anders einzustellen. Ich hab jetzt nicht alle Beiträge auf dem Schirm, aber vielleicht hilft das irgendwie weiter Link. Wenn es nicht helfen sollte, trotzdem schön, dass wir darüber gesprochen haben. Ansonsten fand ich den Beitrag mit den Savepoints eigentlich ganz hilfreich.

mfg

Das Transaktionslevel beeinflusst nur welche Interaktionen zwischen verschiedenen noch nicht committeten Transaktionen möglich sind.
In meinem Fall spielt sich ja alles um eine einzige Transaktion in der der zweite Befehl auf den 1. Aufbaut (Insert auf Create Table).

Savepoints habe ich auch erst durch diesen Thread entdeckt, sind aber in diesem Fall auch uninteressant weil ich nach dem erstellen der Tabelle comitten MUSS.
Und nach einem commit verfallen alle Savepoints der gerade abgeschlossenen Transaktion und ich komme nicht mehr zurück wenn nach dem CREATE TABLE was schief läuft ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:09 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz