Felix_B
Hallo Zusammen!
Ich habe eine Frage bezüglich der Transactions und ob es eine Möglichkeit gibt, diese "global" zu verwenden. Wie man transactions grundsätzlich verwendet ist mir klar.
Folgendes Problem:
Der Zugriff auf die Datenbank erfolgt über mehrere SQLCommands die aus verschiedenen modulen des Programms aufgerufen werden und nicht direkt im zusammenhang stehen.
Ist es nun möglich für alle diese commands ab einem von mir bestimmten Punkt/Zeitpunkt eine "session" zu starten und alles was ab dieser Session vom Programm aus gesendet wird "aufzuzeichnen" und falls gewünscht ein rollback durchzuführen.
Danke, schöne Grüße,
Felix
verwendetes Datenbanksystem: SQL SERVER 2008
(wer rechtschreibfehler findet darf sie behalten)
Felix_B
Danke für den Tipp!
Allerdings ist mir nicht ganz klar wie ich mit dem transaction scope die abfragen verschiedener module "zusammenfassen" kann.
Ein eeispiel hierzu:
Transaktion-start:
Abfrage Modul1 (=dll die für gewissen teil zuständig ist).
Abfrage Modul2 (-.-)
...
Transaktion-ende.
Wie verwende ich nun diese using direktive (vom transaction scope) um aus diesen einzelnen modulen eine "transaktion" zu basteln? Da falls in einem modul ein fehler passiert, muss der rollback auch über änderungen die von vorhergehenden modulen verursacht wurden rückgängig machen.
Habe mir schon etliche "tutorials" und beispiele angeschaut, ohne erfolg.
Ein, zwei Zeilen pseudocode oder eine kleine beschreibung wie ich das teil zu verwenden habe würden mir sehr weiterhelfen!!!!!
Bests,
Felix
FZelle
Du hast es doch schon selber geschrieben, und mit dem Stichwort TransactionScope findest Du in diesem Forum auch Bespiele.
Felix_B
Hab mal versucht das Transaction-scope zu implementieren.
C#-Code: |
using (TransactionScope scope = new TransactionScope())
{
try
{
ExportData(.....);
scope.Complete();
}
catch (Exception eX)
{
}
}
|
Hab nun testhalber währen der transaktionen die verbindung zum server getrennt. wie erwartet wurde eine exception ausgelöst und scope.Complete(); NICHT aufgerufen.
Liege ich richtig in der Annahme, dass beim start des sql servers die noch nicht fertig-gestellten transaktionen durch einen rollback rückgängig gemacht werden? bzw. wie soll man sonst datenverlust bei serverabsturz oder bei einer trennung der verbindung handhaben?
P.s. Alles was in ExportData passiert, läuft über 1 SQL connection die mitgegeben wird. Diese wird 1x vor dem "using" des transaction-scope geöffnet und von allen weitern sqlconnections etc. verwendet. Kann es sein, dass das Transaction-Scope deshalb nicht funktioniert bzw. wie kann ich dem transactionscope die verbindung direkt zuweisen?????
grüße,
Felix
BerndFfm
Hallo Felix,
| Zitat von Felix_B: |
| Liege ich richtig in der Annahme, dass beim start des sql servers die noch nicht fertig-gestellten transaktionen durch einen rollback rückgängig gemacht werden? bzw. wie soll man sonst datenverlust bei serverabsturz oder bei einer trennung der verbindung handhaben? |
Alle innerhalb des Transactionscope erfolgten Befehle, die Änderungen in der SQL-Datenbank bewirken, werden nicht ausgeführt. Ein SQL-Serverstart oder Rollback ist nicht notwendig.
| Zitat: |
| Alles was in ExportData passiert, läuft über 1 SQL connection die mitgegeben wird. Diese wird 1x vor dem "using" des transaction-scope geöffnet und von allen weitern sqlconnections etc. verwendet. Kann es sein, dass das Transaction-Scope deshalb nicht funktioniert bzw. wie kann ich dem transactionscope die verbindung direkt zuweisen????? |
Das ist richtig so. Was funktioniert denn nicht ?
Einem Transactionscope brauchst Du keine Verbindung zuzuweisen. Anders eine normale Transaction, dieser muss man eine Connection zuweisen.
Innerhalb eines Transactionsscope können sogar mehrere Connections zu mehreren SQL-Serverv vorhanden sein.
Was macht Deine Export-Routine ? Ändert sie Daten in der SQL-Datenbank oder exportiert sie Daten aus dem SQL-Server irgendwohin ?
Grüße Bernd
FZelle
@Felix_B:
| Zitat: |
| Alles was in ExportData passiert, läuft über 1 SQL connection die mitgegeben wird. Diese wird 1x vor dem "using" des transaction-scope geöffnet und von allen weitern sqlconnections etc. verwendet. |
Da hast Du aber etwas komplett falsch verstanden.
Wenn du sowieso nur eine Connection für einen Export benutzt, kannst du auch direkt eine normale SqlTransaction benutzen.
Evtl solltest Du nochmal beim Grundlagenwissen zu TransActions nachlesen was das ist.
Felix_B
Es wird zu beginn 1 SQL Connection erstellte und an alle SQLCommands etc. weitergegeben und bis zum beenden des Programms verwendet.
Um das Problem nochmal genau zu erklären:
Ich will nicht von beginn weg alle transactions aufzeichen.
Sondern:
| Zitat: |
| Ist es nun möglich für alle diese commands ab einem von mir bestimmten Punkt/Zeitpunkt eine "session" zu starten und alles was ab dieser Session vom Programm aus gesendet wird "aufzuzeichnen" und falls gewünscht ein rollback durchzuführen. |
Die SQL Connection wird schon zu beginn erstellt um Benutzerdaten/Login abzugleichen und zu authentifizieren. Dies soll natürlich nicht in die "session" mit einfließen. Da die Datenbank extrem komplex ist und sonst unmengen an code benötigt werden würde, wird wie schon erklärt nur 1 SQL Connection zu beginn erstellt um alle weiteren commands etc. zu versorgen. Wie schon beschrieben ist die instanzierung der connection nicht im using block des transactionscopes. In einem gewissen Zeitraum sollte das Transaction scope aber zum einsatz kommen. Wie ist das nun umzusetzen, oder ist dies gar nicht erst möglich?
Grüße, Felix
BerndFfm
Wenn man eine normale Transaction benutzt dann öffnet man eine Connection und die bleibt bis zum Ende der Transaction geöffnet.
TransactionScope dagegen braucht keine Connection, dann kann man immer öffnen und sofort wieder schließen, wie im Artikel "Resourcen schonen" beschrieben. Weiterer Vorteil : Es können Aktionen in mehreren Datenbanken und sogar auf mehreren SQL-Servern in eine Transaktion gepackt werden.
Transaction und TransactionScope hab ich mal gegeneinander getestet : War beides genau gleich schnell.
Bei der Verwendung von TransactionScope hatte ich bei einem Kunden Fehlermeldungen : "Der Manager für verteilte Transaktionen (MSDTC) wurde deaktiviert ..." oder so ähnlich.
Deswegen verwende ich jetzt die normalen Transactions.
Grüße Bernd
Felix_B
So, bin mittlerweile wieder an diesem projekt dran.
Den artikel/Pdf von FZelle über "Datenbanken richtig öffnen und schließen" habe ich gelesen und angewandt.
Mir ist aber immer noch nicht verständlich wie ich nun eine reihe von transactions ab einem gewissen zeitpunkt aufzeichne (unterschiedliche connections!) und z.b. bei verbindungsverlust einen rollback durchführe.
Ein codeschnipsel wäre da sehr hilfreich mit z.b. funktion_a() was irgend ein sql statement ausführt und funktion_b() was im prinzip das selbe macht(!!2 unterschiedlichiche SQL connections).
Grüße,
Felix
FZelle
Ich befürchte du hast da im Moment etwas falsch verstanden.
Warum meinst du jetzt mehr als eine Verbindung zu benötigen?
Und was ist an TransactionScope so schwierig?
Felix_B
Mit zwei verbindungen meinte ich nicht zwei instanzen die gleichzeitig laufen sondern, verbingungsinstanz 1 -> sqlstatement -> verbindung wird geschlossen -> verarbeitung der daten -> verbindungsinstanz 2 -> sqlstatement -> verarbeitung der daten -> userinteraktion -> verarbeitung der daten -> verbingungsinstanz 3 -> sqlstatement -> VERBINDUNGSVERLUST!!! -> alles rückgüng bis zu verbindungsinstanz 1...
so sollte es aussehen. tut mir leid wenn ich da was falsch beschrieben habe.
Grüße,
Felix
Rabban
Hallo Felix_B,
ich bin zwar nicht mit der Technik vertraut die du da nutzt aber warum nutzt du 2 verschiedene Sessions? Normalerweise sollten die Sessions doch Vorgangsbezogen sein.
D.h. Je nachdem was du machen willst, sollten die benötigten Repositories alle mit der gleichen Session initialisert werden.
Wie beim IoC-Pattern(Inversion of Control), oder liege ich da falsch?
MfG
Rabban
FZelle
Deswegen sagte ich du hast das ganze noch nicht so wirklich verstanden.
So wie Rabban das sagt, wäre es richtig.
Eine Verbindung wird für eine einzelne aber komplette Aktion benutzt.
Nennt sich UnitOfWork.