Ich muss respektvoll widersprechen: Transaktionssysteme sind nicht automatisch und ausschließlich Datenbank-Engines, ganz im Gegenteil ...
ich eine Anwendung Transaktionsmechanismus implementiert haben (in .NET), die aus einer Datenbank-Transaktion unterscheidet. Es ist eigentlich ziemlich einfach (ein paar Stunden Arbeit, einschließlich einer Unit-Test-Suite). Es ist vollständig in C# geschrieben, ohne Abhängigkeiten von Datenbankfunktionen oder anderen Komponenten. Aber zuerst einige Kontext ...
Diese nicht-Datenbank-Transaktion Feature existiert in mehreren Manifestationen auf der Java-Plattform, wie mit EJBs, ESBs, JMS und oft in Verbindung mit BPM. Einige dieser Manifestationen verwenden eine zugrunde liegende Datenbank, aber nicht immer und nicht notwendigerweise. Andere Plattformen haben vergleichbare Manifestationen wie MSMQ.
Die meisten älteren Versionskontrollsysteme implementieren keine ACID-Transaktionssemantik. Wie ddaa sagte, tut CVS nicht, sondern Subversion (sein Nachfolger). Visual Source Safe nicht. Wenn Sie Subversion recherchieren, können Sie Vergleichsdiagramme finden, die darauf hinweisen.
Jetzt für den kritischen Punkt, garantiert eine Datenbanktransaktion oder ihre Entsprechung keine sichere Geschäftslogik. Obwohl ich Subversion liebe, ist das ein ironisches Beispiel dafür.
Sie können Subversion religiös verwenden, zusammen mit einem automatisierten Build-Skript (ein Befehl, der Ihre Anwendung kompiliert, testet und packt) und trotzdem einen fehlerhaften Build an das Quellcodeverwaltungs-Repository übergeben. Ich habe es wiederholt gesehen. Natürlich ist es mit nicht-ACID-transaktionsbasierten Quellcodeverwaltungstools wie VSS noch einfacher. Aber es ist für viele Menschen schockierend zu erfahren, dass dies mit Tools wie Subversion möglich ist.
Erlauben Sie mir bitte, das Szenario auszulegen. Sie und ein Mitarbeiter entwickeln eine Anwendung und verwenden Subversion für das Quellcodeverwaltungs-Repository. Sie beide codieren weg und begehen gelegentlich das Repository. Sie nehmen ein paar Änderungen vor, führen einen sauberen Build aus (kompilieren Sie alle Quelldateien), und alle Tests bestehen. Also, du begehst deine Änderungen und gehst nach Hause. Dein Kollege hat an seinen eigenen Änderungen gearbeitet, also führt er auch einen sauberen Build durch, sieht alle Tests bestanden und begibt sich zum Repository. Aber Ihr Mitarbeiter aktualisiert dann das Repository, nimmt einige Änderungen vor, erstellt einen sauberen Build und der Build geht in sein Gesicht. Er ändert seine Änderungen, Updates aus dem Repository wieder (nur um sicher zu sein), und stellt fest, dass ein sauberer Build immer noch explodiert! Ihr Kollege verbringt die nächsten paar Stunden mit der Fehlerbehebung des Builds und der Quelle und findet schließlich eine Änderung, die Sie vor dem Verlassen vorgenommen haben und die den Buildfehler verursacht. Er feuert eine böse E-Mail an Sie, und Ihr gemeinsamer Chef, beschwert sich, dass Sie den Build brach und dann nachlässig nach Hause ging. Du kommst am Morgen an, um deinen Kollegen und deinen Chef zu finden, die an deinem Schreibtisch warten, um dich zu beschimpfen, und alle anderen sehen zu! Du machst also schnell einen sauberen Build und zeigst ihnen, dass der Build nicht kaputt ist (alle Tests sind vergangen, genau wie letzte Nacht).
Also, wie ist das möglich? Dies ist möglich, da die Arbeitsstation jedes Entwicklers nicht Teil der ACID-Transaktion ist. Subversion garantiert nur den Inhalt des Repositories. Wenn Ihr Mitarbeiter aus dem Repository aktualisiert wurde, enthielt seine Arbeitsstation eine gemischte Kopie des Inhalts des Repositorys (einschließlich Ihrer Änderungen) und seiner eigenen nicht festgeschriebenen Änderungen. Wenn Ihr Mitarbeiter einen fehlerfreien Build auf seiner Arbeitsstation ausgeführt hat, hat er eine Geschäftstransaktion aufgerufen, die NICHT durch die ACID-Semantik geschützt war. Als er seine Änderungen rückgängig machte und ein Update vornahm, stimmte seine Arbeitsstation mit dem Repository überein, aber der Build war immer noch pleite. Warum? Da Ihre Workstation auch Teil einer separaten Geschäftstransaktion war, die im Gegensatz zu Ihrem Commit für das Repository auch NICHT durch die ACID-Semantik geschützt war. Da Sie Ihre Arbeitsstation vor dem Ausführen des Bereinigungs-Builds nicht auf das Repository aktualisiert haben, haben Sie die Quelldateien nicht so erstellt, wie sie im Repository vorhanden waren. Wenn Sie ein solches Update durchführen, würden Sie feststellen, dass der Build auch auf Ihrer Workstation fehlschlägt.
Jetzt kann ich auf meinen Ausgangspunkt zeigen - Transaktionen haben Umfang/Kontext, die sorgfältig betrachtet werden müssen. Nur weil Sie eine ACID-Transaktion haben, bedeutet das nicht, dass Ihre Geschäftslogik sicher ist, wenn der Gültigkeitsbereich/Kontext der ACID-Transaktion nicht und die Geschäftslogik GENAU übereinstimmt. Wenn Sie sich auf eine Form der Datenbank-ACID-Transaktion verlassen, aber in Ihrer Geschäftslogik alles tun, was nicht durch diese Datenbanktransaktion abgedeckt ist, haben Sie eine Lücke, die einen vergleichbaren und katastrophalen Fehler ermöglichen kann. Wenn Sie Ihre Geschäftslogik zwingen können, genau mit Ihrer Datenbanktransaktion übereinzustimmen, dann ist alles in Ordnung. Wenn nicht, dann benötigen Sie wahrscheinlich einen separaten Geschäftsvorgang. Abhängig von der Art der ungeschützten Logik müssen Sie möglicherweise einen eigenen Transaktionsmechanismus implementieren.
So, Messaging kann transaktional sein, aber der Bereich ist nur die Nachricht. In Bezug auf das obige Beispiel ist der Subversion-Kontext nur eine individuelle Übergabe an das Repository. Die Geschäftstransaktion ist jedoch ein sauberer Build, der einen viel größeren Umfang umfasst. Dieses spezielle Problem wird üblicherweise gelöst, indem ein sauberer Build zusammen mit einem sauberen Checkout erstellt wird, idealerweise unter Verwendung einer kontinuierlichen Integrationsimplementierung (z. B. über CruiseControl oder dergleichen). Auf den Entwicklerarbeitsstationen muss jeder Entwickler die Disziplin ausüben, um vor einem sauberen Build ein vollständiges Update (oder sogar ein sauberes Auschecken) durchzuführen.
Zur Erinnerung, jede Transaktion hat einen Umfang oder Kontext, der den Schutz begrenzt. Geschäftstransaktionen enthalten oft eine Logik, die den Umfang der von uns üblicherweise verwendeten Transaktionsmechanismen (z. B. eine Datenbank-Engine) überschreitet. Sie müssen möglicherweise den Unterschied ausgleichen. In seltenen Fällen kann es sogar sinnvoll sein, hierfür einen eigenen Transaktionsmechanismus zu schreiben.
Ich habe eine Überarbeitung eines kritischen Geschäftssystems für ein bescheidenes Unternehmen mit neunzig Personen entworfen.Ich fand es notwendig, einen solchen Mechanismus zu implementieren, und ich fand die Erfahrung einfach, lohnend und lohnend. Ich würde es wieder tun, vielleicht ein wenig mehr, aber ich würde mich immer fragen, warum ich nicht nur bei einer Datenbanktransaktion bleiben konnte.
Interessante Post. Über SVN kann das von Ihnen beschriebene Szenario tatsächlich passieren, aber imho ist die Folge einer schlechten SVN-Verwendung: Eine gute Regel besteht darin, die Arbeitskopie vor dem Commit immer zu aktualisieren und alle Änderungen zu überprüfen, die das Update in die Arbeitskopie portieren kann vermeide diese Situationen. –
Ich stimme einer Reihe von dem zu, was du sagst, aber dein Argument über kaputte Builds hat mehr mit schlechter Übung zu tun als mit SVN. In diesem Szenario müssen Sie entweder 1) in Ihrer eigenen Zweigstelle arbeiten oder 2) sicherstellen, dass Sie keine Aktualisierungen erhalten, die Ihren Code beschädigen. –
Ich freue mich über Ihre Kommentare, aber bitte beachten Sie, dass Ihre Vorschläge meinen Standpunkt nachahmen - gute Praktiken der Quellcodeverwaltung führen letztendlich zu einer "Geschäftstransaktion", die die Transaktion "Datenbank" der Quellcodeverwaltung umschließt. –