Announcement

Collapse
No announcement yet.

Multiple transactions are not supported by the database

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Multiple transactions are not supported by the database

    Hallo und schönen Abend,

    habe eine Frage an euch, hoffe ihr könnt mir weiterhelfen

    Vorweg:
    Ich arbeite mit Delphi7, Firebird und teils mit dem Sql-Server 2005.
    Als Datenbankanbindung verwende ich die UniDac-Komponenten

    Bis vor kurzen hatte ich nur mit einer Transaction gearbeitet,
    also
    - Transaction aufgemacht
    - Daten geschrieben (mehrere Tabellen)
    - Transaction commit oder Rollback.

    Nun habe ich dies umgebaut, und nun erstelle ich für jeder Query, also für jede aktion eine eigenen Transaction

    Beispiel
    ADRESSEN:
    - TransAdressen := TUniTransaction.create...
    - TransAdressen.StartTransaction
    - QueryAdressen.sql.text := 'update .... '
    - TransAdressen.commit;

    LIEFERANTEN:
    - TransLieferanten := TUniTransaction.create...
    - TransLieferanten.StartTransaction
    - QueryLieferanten.sql.text := 'update .... '
    - TransLieferanten.commit;

    soweit gut, klappt auch alles wunderbar,
    zumindest beim Firebird-Server.

    Gestern habe ich noch kurz den Sql-Server getestet,
    und wenn ich dort mehr als eine Transaction aufmache,
    dann erhalte ich folgende Fehlermeldung:
    "Multiple transactions are not supported by the database"

    Kennt jemand von euch diese Fehlermeldung?
    oder weiß jemand einen Rat was ich versuchen könnte?

    Danke und schöne Abend
    Oswald

  • #2
    Hallo und guten Tag nochmals,

    ich habe eine weitere Frage,
    den jetzt bin ich mir nicht mehr sicher...

    Ich habe devart angschrieben und mein Problem geschildert,
    und als Antwort habe ich folgendes bekommen

    The point is that SQL Server doesn't support multiple transactions and Interbase supports them. To solve the problem don't start more than one transaction when working with SQL Server.
    Was meint ihr dazu,
    ich dachte die stärke eines Sql-Server sind ja die Transactionen oder habe ich da einen Denkfehler?
    Wie macht ihr das, arbeitet ihr auch nur mit einer Transaction?

    danke Oswald

    Comment


    • #3
      Also ehrlich gesagt, weiß ich gar nicht ob meine Transaktionen parallel laufen. Auf jeden Fall habe ich Jobs die zur gleichen Zeit ausgeführt werden mit Inserts und Updates. Ob diese jedoch die Transaktionen parallel laufen lassen, weiß ich nicht.

      Ich dachte es wäre möglich, da der Server ja mehrere Prozessoren haben kann. Aber wenn es einer von denen sagt, dann wird s dann wohl stimmen. Evtl gehen sie so vor, dass man einen Main Thread hat des nur eine Transaction durchlässt.

      Aber es ist schon komisch, find ich.

      Comment


      • #4
        ich dachte die stärke eines Sql-Server sind ja die Transactionen oder habe ich da einen Denkfehler?
        Du kannst theoretisch beliebig viele Transaktionen parallel haben aber immer nur 1 aktive pro Connection. Heißt du kannst Transaktionen nicht schachteln. Wenn du auf einer Connection eine neue Transaktion auf machst musst du eine eventuell bisher vorhandene Transaktion auf dieser Connection erst abschließen.

        Comment


        • #5
          gibt es evtl ein limit an offenen connections?

          Comment


          • #6
            Hallo,
            danke vorerst für eure Antworten.

            Ralf Jansen:
            Du kannst theoretisch beliebig viele Transaktionen parallel haben aber immer nur 1 aktive pro Connection
            Du meinst ich kann viele Transaktionen erstellen (createn), aber nur eine mit StartTransaction aufmachen, stimmts?
            Was ich dann aber nicht ganz verstehe, wieso kann ich dann beim Firebird-Server mehrere Transaktionen innerhalb einer Connection aufmachen, und beim Sql-Server nicht. Aber im Sql-Server Management Studio Express kann man ja auch mehrere Transaktionen gleichzeitig starten, oder nicht?

            Daman:
            Also ehrlich gesagt, weiß ich gar nicht ob meine Transaktionen parallel laufen
            Also verwendest du auch mehrere Transaktionen. Hast du den nur eine Connection oder für jede Transaktion eine eigene Connection erstellt?



            Wie sollte ich dann folgendes lösen:
            Beispiel:
            Ich öffne das Kundenfenster, und in dem Fenster kann ich verschiedene Daten eintragen, und aus diesem Fenster kann ich weitere Fenster aufmachen
            (Bezugsdaten, Urlaubsdaten usw.) das sind Untertabellen 1:n
            Und alles was in diesem Kundenfenster eingetragen oder gelöscht wird.
            hängt an einer Transaktion.

            Aber ich kann während der Eingabe vom Kunde auch noch weiteres Fenster aufmachen,
            beispiel ein Artikelfenster,
            und in dem Fenster hängen auch wieder Untertabellen 1:n
            wie Kundenpreise, Klassifizierungen, Barkode usw.
            da wäre dann eine weitere Transaktion, und die hat mit der Transaktion vom Kundenfenster nicht zu tun, Also das Commiten vom Kundenfenster darf keinen Einfluss auf das Artikelfenster haben, deshalb habe ich auch eine eigene Transaktion eingebaut.

            Würdet ihr dann für jede Transaktion eine eigene Connection aufmachen
            oder wie würdet ihr das lösen?

            Obwohl ich dennoch der Meinung bin das ein Sql-Server mehrere Transaktionen
            unterstützen sollte, oder doch nicht?

            Hoffe ich habe mich verständlich ausgedrückt
            Danke Oswald

            Comment


            • #7
              ich erstelle jedes mal neue connections

              Comment


              • #8
                Hallo Damian,

                dann werde ich das wohl auch so lösen müssen ...

                Danke euch allen
                Oswald

                Comment


                • #9
                  Was ich dann aber nicht ganz verstehe, wieso kann ich dann beim Firebird-Server mehrere Transaktionen innerhalb einer Connection aufmachen, und beim Sql-Server nicht.
                  Unterschiedliche Datenbanken unterschiedliche Features. Ich würde das als normal ansehen(Auch wenn es natürlich schön wäre wenn einfach alle gleich funktionieren, zumindest Vordergründig)

                  Meine Aussage 'nur 1 aktive Transaktion je Connection' ist aber mit Vorsicht zu genießen und hängt wahrscheinlich auch von der verwendeten Zugriffstechnik ab. Was machen den die Unidac Komponenten? Benutzen die die OleDB Schnittstelle oder ODBC? Machen die das vielleicht sogar selbst nativ? Dann vielleicht nochmal konkret beim Hersteller nachfragen oder nachlesen was die den können. Ansonsten würde ich wenn das Produkt auf n Datenbankmodellen laufen soll grundsätzlich von der defensiven Annahme ausgehen 'immer nur 1 aktive Transaktion je Connection'. Das sollte jede DB beherrschen und jedes Problem sollte auch so erschlagbar sein.

                  Comment


                  • #10
                    Hallo Jansen,

                    dein Argument, "andere Datenbanken, andere Features" ist angenommen und trifft sicher immer wieder zu.
                    Ich werde in Zukunft mehr den Sql-Server einsetzen, ... aber möchte dennoch zu Firebird kompatible bleiben.

                    Jetzt habe ich bei einigen Fenster als Versuch eine eigene Connection eingebaut,
                    hatte zwar Bedenken dass die Geschwindigkeit beim Öffnen etwas hängt, weil ja jedes mal eine neue Connection aufgebaut werden muss, aber klappt wunderbar, und so funktionieren auch die Transaktionen.

                    Ich habe in Unidac folgenden Parameter
                    OleDBProvider
                    und dort kann ich folgende Optionen einstellen
                    Auto, Sql, Native Client, und Compact
                    ich habe das auf Auto belassen

                    soviel ich herausgefunden habe, geht die Verbindung über OleDB.

                    danke und schönen Abend
                    Oswald

                    Comment


                    • #11
                      Hallo Oswald,

                      ich verstehe deine Anforderung so:
                      In einer MDI - Anwendung kann der Nutzer in unterschiedlichen Formularen unterschiedliche Daten erfassen, die z.T. in mehreren Tabellen abgelegt werden. Physisch eröffnest du mit der Anlage des Hauptdatensatzes bzw. mit der ersten Änderung in solchem Formular eine Transaktion. Alle Nutzerdaten werden jetzt erstmal sofort in die DB gespeichert.
                      Wenn der Nutzer mit der Erfassung incl. der Detaildaten fertig ist und <Speichern> drückt, sendest du ein Commit und zurrst damit alles fest.
                      Entscheidet er sich lieber für <Abbruch>, kommt ein Rollback und die Datenbank ist wieder schön und konsistent sauber aufgeräumt.

                      Falls ich damit richtig liege, möchte ich folgendes zu Bedenken geben:

                      Man sollte keine Transaktionen über Benutzereingaben hinweg laufen lassen. Transaktionen belegen immer Ressourcen bzw. verursachen irgendwie geartete Sperren. Selbst bei dirty reads können sich hier - zumindest nach meiner Erfahrung - die komischsten Deadlocks ergeben. Und der sperrende User ist gerade beim Kaffeetrinken.....

                      Transaktionen, so handhabe ich das jedenfalls, sollten kurz und knapp und eigentlich überhaupt nur durch eine Exception unterbrechbar sein.
                      Dafür sind sie in Try / Except eingeschlossen.

                      Je nach Implementierung wundert sich der Nutzer auch schlimmstenfalls, dass er bei einem Abbruch der Barcodeeingabe gleich den ganzen neu angelegten Artikel wieder weggepustet hat.

                      Also, vielleicht ist das ja auch alles sonnenklar und ich habe dich nur falsch verstanden, dann sorry, ich will kein Schulmeister sein.


                      Jedenfalls, ich habe einige doch auch umfangreichere Systeme am laufen und -außer bei der Verwendung mehrerer Threads- reicht mir eine einzige Connection.

                      Sehr selten kommt es mal zu Verschachtelungen, z.B. wenn ich einen Lagerbeleg alleine buche oder aus einem Verkaufsbeleg heraus die Buchung anstoße. (Verkaufsbeleg erzeugt in Transaktion Lagerbeleg und bucht den gleich, anderer Lagerbeleg kann auch manuell erfasst und direkt gebucht werden). Hier schaut der Lagerbeleg, ob schon eine übergeordnete Transaktion aktiv ist.
                      Wenn ja, is gut, wenn nein, macht er seine eigene auf und committet sie auch selber wieder.

                      Ja, sorry viel Text und möglicherweise am Thema vorbei, aber das Thema "Transaktionen über Nutzereingaben" erinnert mich an eine Praxis - Lehrstunde mit einem genialen Programmierer, die ich gleich nach meinem Studium mal haben durfte. Aber das ist eine andere Geschichte und bevor das hier noch länger wird ..

                      Gute Nacht
                      Tino
                      Ich habs gleich!
                      ... sagte der Programmierer.

                      Comment


                      • #12
                        Multiple transactions are not supported by the database
                        Das ist mit Sicherheit keine Meldung vom MS SQL Server. Gab es dazu auch eine Fehlernummer?

                        Du kannst theoretisch beliebig viele Transaktionen parallel haben aber immer nur 1 aktive pro Connection
                        Immer zuerst in die BOL sehen: BEGIN TRANSACTION (Transact-SQL)
                        Man kann problemlos mehrere Transaktion schachteln.
                        [highlight=SQL]
                        BEGIN TRANSACTION
                        SELECT @@Trancount AS AnzTrans
                        BEGIN TRANSACTION
                        SELECT @@Trancount AS AnzTrans
                        BEGIN TRANSACTION
                        SELECT @@Trancount AS AnzTrans
                        COMMIT TRANSACTION
                        SELECT @@Trancount AS AnzTrans
                        COMMIT TRANSACTION
                        SELECT @@Trancount AS AnzTrans
                        COMMIT TRANSACTION
                        SELECT @@Trancount AS AnzTrans
                        [/highlight]
                        Das Problem liegt nicht am SQL Server, sondern an den verwendeten Zugriffskomponenten.
                        Olaf Helper

                        <Blog> <Xing>
                        * cogito ergo sum * errare humanum est * quote erat demonstrandum *
                        Wenn ich denke, ist das ein Fehler und das beweise ich täglich

                        Comment


                        • #13
                          Ja, stimmt, die Meldung kommt offensichtlich von den Devart - Komponenten (Ich verwende SDAC und hab' sie auch schon gesehen).

                          Ich hab' mir bisher noch keine Gedanken darüber gemacht, aber offensichtlich unterstützt devart keine 'benannten' Transaktionen.

                          Wie devart zur oben geposteten Aussage kommen, ist damit natürlich erklärungsbedürftig.
                          Ich habs gleich!
                          ... sagte der Programmierer.

                          Comment


                          • #14
                            Hallo,

                            Tino:
                            du liegst mit deiner Vermutung richtig, und auch dein Gedankengang dass ein User Daten eintippt und dann beispielsweise das Telefon klingelt dann bleibt die Transaktion offen, aber das kann und wird sicher immer wieder passieren, unabhängig ob die Transaktionen klein oder groß sind.
                            Die Sdac sind ja auch von Devart, das müssten fast die gleichen Komponenten wie Unidac sein, hat nur mit der Unterstützung von Sql-Server. In den Unidac könnte man die "Network Library" zuweisen, ich weiß aber nicht wie das geht, ob das eine DLL ist … hast du auch diese Einstellung unter den "SpecificOptionen"?

                            Olaf:
                            Ich weiß dass man im Sql-Server mehrere Transaktionen aufmachen kann, und bin auch der Meinung dass diess am Devart liegen muss, aber jetzt muss ich halt die beste Lösung suchen, ein Austausch der Komponente wäre viel zu großer Auwand.

                            Was meint ihr zu den obengenannten Vorschlag, bei jeder neuen Transaktion eine neue Connection aufmachen, das habe ich schon getestet und würde auch funktionieren?


                            Danke
                            Oswald

                            Comment


                            • #15
                              Hallo,

                              du hast ja jetzt offensichtlich schon eine funktionierende "Test" -Anwendung basierend auf mehreren Connections.

                              Mit dieser würde ich zunächst mal einen Mehrbenutzerbetrieb irgendwie simulieren, z.B. einfach die Anwendung mehrfach starten.

                              Dann in Instanz A die Kundenneuanlage beginnen, aber nicht abschließen. Jetzt in Instanz B versuchen einen Kunden komplett neu anzulegen.

                              Würde mich mal interessieren, was passiert.

                              Schon der in (A) vergebene Primärschlüssel ist zunächst für (B) unsichtbar da noch nicht committed. Wie bekommt (B) jetzt seinen Schlüssel ..

                              Wie gesagt, ich sehe da große Probleme.

                              Aber Versuch macht kluch, vielleicht denke ich auch zu kompliziert.

                              Viel Erfolg
                              Tino
                              Zuletzt editiert von tinof; 17.12.2010, 17:23.
                              Ich habs gleich!
                              ... sagte der Programmierer.

                              Comment

                              Working...
                              X