ich habe eine Software (.Net 3.5, VB.NET / C#) die jeweils an mehereren Arbeitsplätzen bei insgesamt 160 Unternehmen läuft.
Als DB Backend dient pro Unternehmen ein SQL 2008R2 Server.
An einem der Rechner läuft pro Unternehmen ein "UpdateChecker" der prüft ob auf einem FTP Server ein Update für die Software bereit liegt.
Liegt hier ein neues Update vor, zeigen alle Arbeitsplätze "Update einspielen" an. Wenn nun an einem der Arbeitsplätze das Update gestartet wird, werden an dem Server zunächst die Constraints entfernt um anschliessend Tabellenstruktur usw. Updaten zu können. Anschliessend werden die Constraints wieder hergestellt und das Update ist abgeschlossen.
Stand heute ist allerdings das alle anderen Arbeitsplätze nicht mitbekommen das gerade ein "Update" läuft und somit trotzdem noch in die DB schreiben dürfen. Dies muss selbstverständlich verhindert werden.
Ich habe mehrere Ideen wie ich diesen "Sperrmodus" umsetzten kann. Allerdings interessiert mich ob es hierfür eine "Best Practise" gibt bzw. wie ihr das lösen würdet.
Möglichkeit 1: DB Updates prüft der Server und nicht der Client und führt diese aus. Dazu sperrt er die DB, wenn keiner mehr darauf zugreift, führt das Update aus und gibt wieder frei. Vorteil: Der Server läuft immer und könnte es also auch Nachts eigenständig durchführen.
Möglichkeit 2: Der Client der das Update ausführt, schreibt einen Versionsstring in eine Tabelle. Die restlichen Clients müssen vor Zugriff prüfen ob ihr beim Start der Anwendung gelesener Versionsstring noch passt, bevor geschrieben wird.
Möglichkeit 3: Kommunikation der Clients untereinander über einen WCF Service. Dann können die eine entsprechende Mitteilung machen auf die reagiert wird.
Ich würde die Clients nicht direkt in die DB schreiben lassen, sondern ein kleine Server-Applikation davor setzen. Dann kann darüber auch der Zugriff gesperrt werden. Ist ein bestimmtes Flag gesetzt, dann gibt der Server eine Fehlermeldung zurück.
Wie bekommen den die Clients mit das auf dem Server eine neues Update liegt ? Der Updatechecker läuft ja auf nur einem Rechner. Falls du zyklisch die Datenbank pollst kannst du ja auch ein Flag in einer Service-Tabelle setzen welches besagt, dass ein Update installiert wird und die Clients das entsprechend nichts mehr in die DB schreiben.
Falls du nicht pollst oder pollen willst gibt es die SQLDependency's. Dazu musst du auf dem SQL Server den Broker Dienst aktivieren und eine Queue einrichten. Vorstellen musst du dir das so wie einen Callback des SQL Servers in deine Clients. D.h. der SQL Server ruft eine Funktion in deiner Software auf falls eine Tabelle oder Spalte einen bestimmten Wert enthält. Dazu kannst du wiederum einen Trigger in der Datenbank verwenden.
Hoffe das hilft dir weiter. Ich hatte das mal eingesetzt um Clients mitzuteilen dass sich die Daten in der Datenbank geändert haben, ohne über einen Application Server zu gehen. Hat sehr gut funktioniert und ist sauber von der Architektur. Es wird nichts gepollt und lässt sich einfach integieren.
Die einfachste und sicherste Option ist die Datenbank exklusiv zu sperren, d.h. den Restricted User Mode zu aktivieren. Hierbei müssen jedoch vorher alle offenen Verbindungen getrennt werden.