Arten von Migrationen

Datenbankmigrationen

Datenbankmigrationen werden ausgeführt, wenn die Anwendung nach einem Update zum ersten Mal startet. Dies erfolgt in 4 Schritten:

  1. Vor dem Start
    Datenbankänderungen die den Start des ORM-Mappers verhindern.
  2. Nach dem Schema-Update
    Datenbankänderungen, die bereits die aktualisierten Datenbanktabellen benötigen.
  3. Konfigurationsmigration
    Aktualisierung der Konfiguration in der Datenbank = Variante von “Konfigurationsmigrationen”
  4. Nach dem Start
    Anpassungen, die eine initialisierte Anwendung voraussetzen.

Konfigurationsmigrationen

Konfigurationsmigrationen können sowohl beim Anwendungsstart (Schritt 3) als auch beim Import (älterer) Konfigurations-ZIPs ausgeführt werden.
Für Konfigurationsmigrationen gibt es eine spezielle Basisklasse: ConfigurationMigrationBase. Wird eine Konfigurationsmigration anders implementiert, funktioniert sie im Allgemeinen beim Import älterer Konfigurations-ZIPs nicht.

Migrationsnummern

Eine Migration wird über eine Nummer Identifiziert. Diese besteht aus 4 Komponenten:

  1. Hauptversionsnummer des Moduls (=Assembly), zum Zeitpunkt der Erstellung, maximal zweistellig, entspricht der ersten Stelle der AssemblyFileVersion.
  2. Unterversionsnummer des Moduls (=Assembly), zum Zeitpunkt der Erstellung, maximal zweistellig, entspricht der zweiten Stelle der AssemblyFileVersion.
  3. Laufende Nummer des Migrationsskripts innerhalb der eben genannten Version/Unterversion, maximal zweistellig, beginnend bei 1.
  4. Versionsnummer des Migrationsskriptes, optional, maximal zweistellig.

Die Migrationsnummer muss für jede Migrationsklasse definiert werden.

Beispiel:

[MigrationScript("0.9", 2)]

Das bedeutet, das zweite Migrationsskript innerhalb der Modulversion „0.9“.

Darstellung von Migrationsnummern

Modul- und Migrationsversionen werden intern numerisch als Ganzzahl dargestellt. Die Ganzzahl verwendet immer zwei Stellen pro Teil der vollen Modulversion.

Beispiel:
Volle Modulversion lautet „1.2.17.0“, damit wäre die numerische Darstellung „01021700“, die führende Null entfällt natürlich beim Ablegen als Ganzzahl. Die einzelnen Versionsteile dürfen maximal zweistellig sein.

Ausführungsreihenfolge

Alle Migrationen, werden je Migrationsschritt modulweise durchgeführt, das heißt für BACRM beispielsweise:

  1. Vor dem Start, BA Core
  2. Vor dem Start, BA Core Erweiterungsmodule (Designer)
  3. Vor dem Start, BA Module
  4. Vor dem Start, BACRM Module
  5. Vor dem Start, BA.CRM
  6. Vor dem Start, Projekt Erweiterungen
  7. Nach dem Schema-Update, BA Core
  8. Nach dem Schema-Update, BA Core Erweiterungsmodule (Designer)

Innerhalb jedes einzelnen Schrittes erfolgt die Ausführung in der Reihenfolge der Migrationsnummer. Ausnahme: Migrationsskriptversionen.

Migrationsskriptversionen

Wird eine Migration nachträglich verändert, so kann man ihre Migrationsskript-Versionsnummer um eins erhöhen. Beispiel:

[MigrationScript("0.9", 2, 1)]

Das gibt die Version 1 des Skripts und führt dazu, dass dieses Skript erneut ausgeführt wird, auch dann, wenn es in der älteren Version schon gelaufen ist oder längst Nachfolgeskripte gelaufen sind.

Es obliegt dem Migrationsskript, das dieses Feature verwendet, selbst, dabei nicht auf Fehler zu laufen. Das Skript kann über das Kontext-Objekt prüfen, ob und in welcher Version es vorher schon einmal gelaufen ist.

Kompatibilitätsgrenzen

Über Assembly-Attribute kann festgelegt werden, welche alten Datenbestände für eine Migration noch unterstützt werden. Beispiel:

[assembly: MigrationCompatibilitySource("0.7")]

Dieses Attribut erzwingt, dass die Daten für eine Migration selbiger (oder Konfiguration-ZIPs) mindestens der genannten Versionsnummer des eigenen Moduls entstammen müssen. Ältere Datenbestände müssen zunächst auf eine Zwischenversion der Anwendung migriert werden, die den Datenbestand noch unterstützt.

Die Überprüfung erfolgt modulweise. Nur wenn alle Module ihre jeweilige Vorgängerversion unterstützten, ist ein Anwendungsstart möglich.

Wenn die Kompatibilitätsversionsnummer erhöht wird, können alle Migrationen bis einschließlich zu dieser Versionsnummer aus dem Code entfernt werden. 

Sonderfall Service-Releases

Bei Service-Releases kann es vorkommen, dass eine vermeintlich kleinere Versionsnummer nach einer größeren erscheint. Beispiel, in Erscheinungsreihenfolge:

  • V0.8
  • V0.8.1
  • V0.9
  • V0.8.2
  • V0.9.1

Dies führt dazu, dass eine Migration von V0.8.2 auf 0.9 nicht allgemein unterstützt wird. Die Migrations-Engine nutzt dazu das Build-Datum der Module. Dieses darf sich bei einer Migration nicht reduzieren.

Sollte V0.8.2 unmittelbar nach V0.9 erschienen und eine Kompatibilität dennoch gewährleistet sein, muss das mit einem weiteren Attribut explizit erlaubt werden. Und zwar muss die später erschienene Version V0.8.2 ein Upgrade auf V0.9 erlauben. Es können auch mehrere Versionen erlaubt werden.

[assembly: MigrationCompatibilityTarget("0.9")]

Dieses Attribut ist beim Erscheinen eines neuen Service-Release im Allgemeinen zu entfernen oder zumindest neu zu bewerten.