Laden...

Lösungsansatz zur Nebenläufigkeit: Datensatzsperre

Erstellt von Rocket vor 14 Jahren Letzter Beitrag vor 14 Jahren 6.142 Views
R
Rocket Themenstarter:in
240 Beiträge seit 2007
vor 14 Jahren
Lösungsansatz zur Nebenläufigkeit: Datensatzsperre

Hi,

2 User können gleichzeitig auf einen Datensatz zugreifen.

Wie könnte man am Besten verhindern, dass alle vorherigen Änderungen des 1. User mit denen des 2. Users überschrieben werden?

731 Beiträge seit 2006
vor 14 Jahren

Hi Rocket,

ganz einfach indem Du den gleichzeitigen Zugriff verhinderst. 😃

MfG
wax

T
511 Beiträge seit 2008
vor 14 Jahren

Google: Datensatz locking

Nicht für das Leben, für die Arbeit lernen wir ...
Windows ist Klasse, ich nehme es um Linux zu downloaden ....

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo Rocket,

bisschen allgemein deine Frage. Hier ein ähnlich allgemeine, aber sicher sehr hilfreiche Antwort: [Artikel] Multi-Threaded Programmierung. Wenn man nebenläufige Programme schreibt, sollte man allen entsprechenden Grundlagen gut kennen, sonst fliegt man schnell auf die Schnauze. Also lies dich am besten erstmal gründlich in das Thema ein.

herbivore

R
Rocket Themenstarter:in
240 Beiträge seit 2007
vor 14 Jahren

@herbivore

Mit Threads habe ich schon gearbeitet.
Habe mir aber trotzdem das PDF durchgelesen und bin auf folgenden Satz gestoßen:

"Man mussals Entwickler nur immer darauf aufpassen, dass Ressourcen immer nur von einem Thread gleichzeitig verwendet werden. Dies geschieht mithilfe von Synchronisierung."

Doch leider steht dazu nicht mehr in dem Dokument...

@Toem99
An der Sperrung des Datensatzes hab ich auch schon gedacht.
Jedoch wie könnte man das optimal umsetzen?
Sollte es eine UserID Spalte geben in dem der aktuelle Benutzer, der den Datensatz gerade bearbeitet?

F
10.010 Beiträge seit 2004
vor 14 Jahren

Naja, kommt ja drauf an, wie du das schreiben in die DB gelöst hast.

Wenn du den std mechanismus mit dem CommandBuilder benutzt, bekommst du bereits
eine ConcurencyException, du kannst also die Änderungen garnicht speichern.

R
Rocket Themenstarter:in
240 Beiträge seit 2007
vor 14 Jahren

Ich benutze einen Standard Mechanismus indem ich Commands manuell erstelle und mit ExecuteScalar etc. ausführe.

Woher weiß denn der CommandBuilder das er eine ConcurencyException werfen soll?

S
443 Beiträge seit 2008
vor 14 Jahren

Ich glaub da sind generell noch ein paar Fragen offen.

Sollen die Änderungen nicht überschrieben werden? oder soll der 2. Benutzer daran gehindert werden etwas an den Daten zu ändern?

Beachte, die Daten zu ändern sind im Zeitablauf vor dem Speichern

  1. Benutzer 1 : andert Feld 1
  2. Benutzer 2 : andert Feld 2
  3. Benutzer 1 : andert Feld 3
  4. Benutzer 2 : andert Feld 3
  5. Benutzer 1 : speichert
  6. Benutzer 2 : speichert

Wann soll wer informiert werden? was soll bei 6. passieren

mbg
Rossegger Robert
mehr fragen mehr wissen

Montag morgen ist die beste Zeit um eine erfolgreiche Woche zu beginnen

F
10.010 Beiträge seit 2004
vor 14 Jahren

@Rocket:
Und warum machst du es so umständlich?

Der CommandBuilder baut in das Update dann eine Where Clausel, in der
die Ursprungswerte der einzelnen Felder stehen.

R
Rocket Themenstarter:in
240 Beiträge seit 2007
vor 14 Jahren

@FZelle

Hab gehört der CommandBuilder ist manchen Szenarien nicht so performant.

@spike24
Also hab mir das so vorgestellt, daß der 2. User den Datensatz erst gar nicht berarbeiten darf, wenn dieser gerade vom 1. User bearbeitet wird.
Nach dem speichern, soll der Datensatz wieder freigegeben werden.
Evtl. wollte ich eine Änderungsliste anbieten, sodaß der User weiß was geändert wurde...

Dabei sind aber noch ein paar Probleme bewußt geworden.
Z.B: Was passiert, wenn das Programm während der Bearbeitung abstürzt!?

S
443 Beiträge seit 2008
vor 14 Jahren

Hab gehört der CommandBuilder ist manchen Szenarien nicht so performant.

Irrelevant.
Ohne Deinen Programmcode zu kennen verbratest Du an anderer Stelle das 100fache. Ohne es zu wissen. Versprochen.

Wenn das Programm von User 1 abstürzt hält User 1 das Lock auf den Datensatz bis in die nächste Ewigkeit, das kann unter Umständen dauern. Geht man nach Hollywood bis 2012 😉
Ausser Du hast ein "Programmteil" das dieses Lock nach z.b. 1 Minute entfernt. Aber nur wenn sich der Client nicht regelmässig meldet, es kann ja sein, das ein Client das Fenster nur offen hat, aber nicht ständig daran was ändert.

Grunsätzlich:
Um sowas zu implementieren, wirst Du Dein Framework mal aufbohren müssen.
Wenn Du Dich in http://www.mycsharp.de/wbb2/thread.php?threadid=32405 auskennst, wird Dir das ungemein helfen.

Als Erstes brauchst Du eine Stelle welche das locking übernimmt:
Wenn sich ein Client meldet locken, das regelmässige locken empfangen kann, falls kein regelmässiges locken mehr kommt, das lock entfernt, und das lock entfernt wenn es der Client nicht mehr braucht (nach dem Speichern)
Wir haben uns dafür einen Service geschrieben mit den Methoden Acquire und Release
Der Client erzeugt einmalig einen SessionToken (UserName?) und übergibt bei Acquire diesen Token, den Typ des zu sperrenden Objects und die entsprechende Id.
Bei Release das gleiche.
Hint:
im LockingService haben wir ein Dictionary<DtoReference, SessionToken> wo gemerkt wird wer was gelockt hat und ein zweites Dictionary vom Type Dictionary<SessionToken, DateTime>
DtoReference.Properties = Type und Id, des Objektes.

Der Rest ist dann eigentlich eine einfache Sache wenn man den oberen Link intus hat. vor dem Property ändern geht man zum LockingService und fragt nach ob man den Lock auf das Objekt bekommt, wenn ja, dann führt man die Änderung durch wenn nein wirft man eine StateChangingCanceledExcption.

Das war eigentlich der ganze Zauber.

mbg
Rossegger Robert
mehr fragen mehr wissen

Montag morgen ist die beste Zeit um eine erfolgreiche Woche zu beginnen

R
Rocket Themenstarter:in
240 Beiträge seit 2007
vor 14 Jahren

Hi Spike24,

danke für die Info.
Hab bisher nur von AOP gehört, aber es noch nicht angewendet.
Wird allerhöchste Zeit sich in das Thema einzuarbeiten (-;

Ich habe nochmal einige Frage zu eurem Locking Service.

Wir das Locking bei euch nur im Speicher gehalten oder habt ihr in der DB noch ein Hinweis auf den gelockten Datensatz?

Ist der Service als Singleton implementiert?

In was für einem Szeanrio setzt ihr euren Service ein?
Web- oder Windows-Client.

S
443 Beiträge seit 2008
vor 14 Jahren

Hi Spike24,
Wird allerhöchste Zeit sich in das Thema einzuarbeiten (-;

jep

Wir das Locking bei euch nur im Speicher gehalten oder habt ihr in der DB noch ein Hinweis auf den gelockten Datensatz?

nur im Speicher, wenn der LockingService stirbt, darf er keine Spuren hinterlassen

Ist der Service als Singleton implementiert?

Singelton, wobei die Frage nicht ganz verstehe, einen Service gibt es generell nur einmal, egal wieviele Verbindungen vom Client geöffnet werden

In was für einem Szeanrio setzt ihr euren Service ein?
Web- oder Windows-Client.

bei uns in Windows, wobei ich hier ebenfalls die Frage nicht ganz verstehe, den einem Service ist es ziemlich egal wer darauf zugreift.

mbg
Rossegger Robert
mehr fragen mehr wissen

Montag morgen ist die beste Zeit um eine erfolgreiche Woche zu beginnen

S
443 Beiträge seit 2008
vor 14 Jahren

Anmerkung am Rande:
wenn Du Locking einbaust, brauchst Du auch unbedingt VersionHandling.
Was nützt es wenn du den gleichzeitigen zugriff verhinderst, wenn man auf einer alten Version des Datensatzen speichern darf?

mbg
Rossegger Robert
mehr fragen mehr wissen

Montag morgen ist die beste Zeit um eine erfolgreiche Woche zu beginnen

F
10.010 Beiträge seit 2004
vor 14 Jahren

@Rocket:
Nur wozu das ganze, wenn du es mit den einfachen std mitteln von ADO.NET schon gelöst bekommen hast?

S
443 Beiträge seit 2008
vor 14 Jahren

Er will die Exception schon vor dem Bearbeiten des ersten Properties durch User 2 bekommen, das geht leider mit .Net Mitteln von Hausaus nicht, zumindest nicht meines Wissens.

mbg
Rossegger Robert
mehr fragen mehr wissen

Montag morgen ist die beste Zeit um eine erfolgreiche Woche zu beginnen

R
Rocket Themenstarter:in
240 Beiträge seit 2007
vor 14 Jahren

@Fzelle
Ich suche ja momentan noch eine Lösung. Hab da noch nichts umgesetzt...
Außerdem habe ich noch ein paar andere Themen, die ich mit AOP lösen möchte...

@spike24

Singelton, wobei die Frage nicht ganz verstehe, einen Service gibt es generell nur einmal, egal wieviele Verbindungen vom Client geöffnet werden

Ich hab dabei nur an Singleton WCF Services gedacht die man so deklariert:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

bei uns in Windows, wobei ich hier ebenfalls die Frage nicht ganz verstehe, den einem Service ist es ziemlich egal wer darauf zugreift.

Momentan ist mir entfallen was ich da eigentlich mit fragen wollte 😁

wenn Du Locking einbaust, brauchst Du auch unbedingt VersionHandling.
Was nützt es wenn du den gleichzeitigen zugriff verhinderst, wenn man auf einer alten Version des Datensatzen speichern darf?

Ich habe das eigentlich so angedacht, das der User erst gar nicht den gesperrten Datensatz aus einer Übersicht zum Bearbeiten auswählen kann.
Nach der Freigabe kann er erst den Datensatz im Detail Fenster bearbeiten...
Damit ist dann sichergestellt, daß er immer die aktuellsten Daten zur Verfügung hat...

S
443 Beiträge seit 2008
vor 14 Jahren

So fit bin ich in Services nicht, das Attribute kenn ich nicht, aber wenn Du Dich in WCF einliest wirst Du es herausfinden 😉

Für einen WCF Service (oder Service im allgemeinen) ist es egal wer darauf zugreift, solange die "Sprache" stimmt (Protokoll)

Du willst dem Benutzer die DetailAnsicht, welche meist durch das Bearbeiten-Fenster zu erreichen ist, verwehren?

// Edit:
hab mir das Attribute gerade ein bisschen angesehen, und ich glaube es ist nicht das was Du haben willst, bzw. ich empfehle es nicht.
Soweit ich das verstanden habe:
mit diesem Attributte (mit dieser Einstellung) darf nur ein Aufruf im Service herumgurken, alle anderen Aufrufe müssen vor der Türe warten bis der davor wieder raus ist.
Das kann grausame nebenefekte haben, wie z.b. TimeOutException.
Die Abarbeitung eines Aufrufes dauert 10 sec, TimeOut ist auf 60 sec eingestellt, es kommen zugleich 7 Aufrufe.

Würde da eher dahin tendieren, dass Du das Service Multithreading sicher machst.

mbg
Rossegger Robert
mehr fragen mehr wissen

Montag morgen ist die beste Zeit um eine erfolgreiche Woche zu beginnen

R
Rocket Themenstarter:in
240 Beiträge seit 2007
vor 14 Jahren

@spike24

Du willst dem Benutzer die DetailAnsicht, welche meist durch das Bearbeiten-Fenster zu erreichen ist, verwehren?

Nicht ganz verwehren. Evtl. nur ReadOnly anzeigen.
Hast du einen besseren Vorschlag?

wenn Du Locking einbaust, brauchst Du auch unbedingt VersionHandling.
Was nützt es wenn du den gleichzeitigen zugriff verhinderst, wenn man auf einer alten Version des Datensatzen speichern darf?

Habt ihr das Verionhandling auch mit AOP implementiert?

S
443 Beiträge seit 2008
vor 14 Jahren

Hast du einen besseren Vorschlag?

Besser ist Ansichtssache, aber eben wie oben beschrieben, direkt an die Property geweavt eine überprüfung ob das objekt nicht gerade gelockt ist.
Wenn es direkt in der Property steht hat es den Vorteil, es kann nicht unabsichtlich durch den Code passieren und da kann es manchmal Situationen geben wo ein objekt verändert wird ohne es direkt zu bedenken.

Habt ihr das Verionhandling auch mit AOP implementiert?

Nein, das ist in der Datenbank ein einfaches Feld mit einem long.
Wir haben Oracle und da wirft irgendein Trigger eine Exception.
Bei anderen Datenbanken, wie z.b. Access o.ä. müsstest Du es in den SQL-Statemement mit einbauen.

UPDATE Tabelle SET Feld = Wert WHERE Version = {Version des lokalen Objektes}

wenn beim Command.ExecuteScalar 0 zurückkommt hat sich die Version verändert. Kann natürlich auch andere Gründe haben, aber die sollten durch testing abgedeckt und vermieden werden können.

mbg
Rossegger Robert
mehr fragen mehr wissen

Montag morgen ist die beste Zeit um eine erfolgreiche Woche zu beginnen

F
10.010 Beiträge seit 2004
vor 14 Jahren

Der SqlServer hat hierzu den Datentyp TimeStamp ( nicht zu verwechseln mit DateTime).

Nurt wozu dieser ganze Aufwand?

Bereits der std CommandBuilder bietet die Möglichkeit beim speichern der Daten zu
testen ob der Datensatz zwischendurch geändert wurde, und schmeisst eine Exception.
(Kann man aber auch ausschalten und Last Win erzeugen lassen ).

Und egal wie du das Locken machst, kann es immer Situationen geben, in denen
zwei Anwender doch irgendwie den gleichen Datensatz bearbeiten, also hast du den
ganzen Lockingmechanismuss dann "umsonst" implemetiert.

R
Rocket Themenstarter:in
240 Beiträge seit 2007
vor 14 Jahren

@FZelle

Nurt wozu dieser ganze Aufwand?

Das ist eine gute Frage.
Ich versuche ja zur Zeit eine optimale Lösung zu finden...
Wenn der CommandBuilder eine Exception wirft, ist die Frage, wie man
darauf reagiert.
Dem User wird mitgeteilt, dass sich der Datensatz in der Zwischenzeit geändert hat.
Was macht man nun mit dem User?
Was passiert mit seinen Daten?

F
10.010 Beiträge seit 2004
vor 14 Jahren

Das entscheidest der Projektverantwortliche/Kunde.

Du kannst nachfragen, ob trotzdem gespeichert werden soll, und dann ggf
eben mit einem CommandBuilder mit LastWin configuration speichern.
Oder die Daten verwerfen.
Oder immer überschreiben.

X
1.177 Beiträge seit 2006
vor 14 Jahren

huhu,

Oder nachgucken welche Daten sich geändert haben und dem User anzeigen, damit dieser Entscheidet welche Daten er will.
Oder die Daten Mergen, wenn sich unterschiedliche Daten geändert haben. (s.B. einmal der Name, einmal die Telefonnummer)

Auch ein Locking kann Probleme machen (Was ist, wenn die beiden User unterschiedliche Daten desselben Datensatzes bearbeiten?)

etc.

Für genau diese Problem gibt es keine Grundsätzliche Lösung. Es ist immer der Anwendungsfall der zählt. Willst Du immer mit dem Server verbunden sein müssen? Werden daten evtl. lokal gehalten weil der Zugriff übers Internet langsam ist?

😃

Xynratron

Herr, schmeiss Hirn vom Himmel - Autsch!

Die Erfahrung zeigt immer wieder, dass viele Probleme sich in Luft auslösen, wenn man sich den nötigen Abstand bzw. Schlaf gönnt.

1.564 Beiträge seit 2007
vor 14 Jahren

Hallo Rocket

Wie Xynratron bereits scheibt (und spike24 angedeutet hat), es gibt beim Thema Locking nicht die Lösung.

Pessimistisches Locking beschreibt spike24. Also vor dem Editieren entscheiden ob ein Benutzer den Datensatz bearbeiten darf.

Optimistisches Locking beschreibt FZelle. Also nach dem Editieren und vor dem Speichern entscheiden ob die Änderungen übernommen werden sollen.

Xynratron hat zusätzlich noch einen optimistischen Ansatz mit einem Merge aufgebracht. Also bei Konflikten den Benutzer entscheiden lassen ob und was überschrieben werden soll.

Bei pessimistischem Locking stellt sich außerdem die Frage welche referenzierten Objekte noch gelockt werden sollen. Locke ich beispielsweise, wenn ein Kundendatensatz angezeigt wird auch die Bestellungen des Kunden (kann ja sein, dass der Kunde wegen fehlender Bonität gesperrt werden soll)? Locke ich beim öffnen einer Bestellung auch die Bestellpositionen? Oder sogar die bestellten Produkte (kann ja sein dass gerade der Preis geändert werden soll). Und und und...

Nächste Frage beim Pessimistischen Locking ist ob das dann nur für andere schreibende Aktionen oder auch für lesende Operationen gelten soll. Wenn du hier z.B. deine AOP verwendest kannst das bedeuten, dass alle Übersichtsanzeigen für die Bestellungen eines Tages nicht mehr funktionieren (oder zu wenig anzeigen) sobald einer eine Bestellung zum editieren geöffnet hat.

Wie du siehst. Es gibt viele Fragen die du (oder euer Team) erstmal mit dem Kunden klären müsst. Die kann dir IMO hier keiner abnehmen. Alle Ansätze haben ihre Vor- und Nachteile.

Wie Xynratron (und Martin Fowler 😉 ) sagen, Locking ist nicht nur eine Lösung für Probleme, es bringt auch immer viele Probleme mit sich.

Wenn's irgendwie möglich ist bevorzuge ich den Last-Save-Wins Ansatz. Um sicherzustellen dass nix verloren geht würde ich hier Audit-Tabellen verwenden und die mit einem Trigger befüllen lassen. (Da sind alle clientseitigen Lösungen wesentlich umständlicher - wenn's korrekt sein soll.)

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

3.825 Beiträge seit 2006
vor 14 Jahren

Hallo Leute,

ich mache das so (pessimistisches Locking) :

jeder Datensatz wird erstmal angezeigt. Wenn ein Benutzer etwas ändern möchte muss er erst auf "Ändern" drücken.

Wenn der zweite Benutzer den gleichen Datensatz ändern will dann bekommt der die Meldung "Dieser Datensatz wird gerade vom Benutzer XY (IP 192.168.1.1) bearbeitet und kann deshalb nicht geändert werden".

Die IP-Nummer zeige ich an damit man dem User auf die Finger klopfen kann wenn er einen Datensatz sperrt und dann in die Mittagspause geht.

Stürzt ein Rechner ab werden alle Sperren und alle reservierten Nummern des Benutzers nach 3 min. freigegeben.

Bei pessimistischem Locking stellt sich außerdem die Frage welche referenzierten Objekte noch gelockt werden sollen. Locke ich beispielsweise, wenn ein Kundendatensatz angezeigt wird auch die Bestellungen des Kunden (kann ja sein, dass der Kunde wegen fehlender Bonität gesperrt werden soll)?
Locke ich beim öffnen einer Bestellung auch die Bestellpositionen? Oder sogar die bestellten Produkte (kann ja sein dass gerade der Preis geändert werden soll) ?

Nein - Nein - Nein
Ist nicht notwendig.

Nächste Frage beim Pessimistischen Locking ist ob das dann nur für andere schreibende Aktionen oder auch für lesende Operationen gelten soll. Wenn du hier z.B. deine AOP verwendest kannst das bedeuten, dass alle Übersichtsanzeigen für die Bestellungen eines Tages nicht mehr funktionieren (oder zu wenig anzeigen) sobald einer eine Bestellung zum editieren geöffnet hat.

Wie du siehst. Es gibt viele Fragen die du (oder euer Team) erstmal mit dem Kunden klären müsst. Die kann dir IMO hier keiner abnehmen. Alle Ansätze haben ihre Vor- und Nachteile

Bei mir gilt das Locking nur für sperrend-lesende Operationen. Nur Lesen geht immer. Alle Übersichtsanzeigen zeigen die richtigen Werte.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

1.564 Beiträge seit 2007
vor 14 Jahren

Hi Bernd

Wie ich schon sagte, es kommt ganz drauf an wofür man was braucht.

Bei pessimistischem Locking stellt sich außerdem die Frage welche referenzierten Objekte noch gelockt werden sollen. ...
Nein - Nein - Nein
Ist nicht notwendig.

Wieso?
Beispiel:
Bestellsystem, einem Kunden wird gerade - aus welchem Grund auch immer - ein allgemein gültiger Rabatt eingeräumt. Parallel läuft der Abrechnungslauf los der die Bestellungen in das Buchhaltungssystem überträgt. BOOM

Anderes Beispiel (mit dem ich zu tun habe)
In dem Projekt in dem ich arbeite werden Sendungen und Pakete verarbeitet. Es ist möglich eine Sendung zu öffnen auf on-hold zu setzen. In diesem Fall dürfen keine Pakete der Sendung mehr verladen werden. Parallel laufen im Lager die Arbeiter rum und scannen Pakete auf LKWs. BOOM

... nur für andere schreibende Aktionen oder auch für lesende Operationen...

Bei mir gilt das Locking nur für sperrend-lesende Operationen. Nur Lesen geht immer. Alle Übersichtsanzeigen zeigen die richtigen Werte.

Kommt auch wieder drauf an. Bestellsystem, Kunde ruft an und gibt eine neue Adresse an die jetzt gerade angepasst wird. Parallel wird der Lieferschein für den Verlader ausgedruckt.

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

3.825 Beiträge seit 2006
vor 14 Jahren

Hallo Florian,

bei mir geht das so :

Beispiel:
Bestellsystem, einem Kunden wird gerade - aus welchem Grund auch immer - ein allgemein gültiger Rabatt eingeräumt. Parallel läuft der Abrechnungslauf los der die Bestellungen in das Buchhaltungssystem überträgt. BOOM

Ach was !
Bei mir werden die Rechnungen im Stapel an die Buchhaltung übergeben. Eine Rechnung die gerade bearbeitet wird, um z.B. Rabatt einzutragen, kann nicht übertragen werden.
Eine bereits übertragene Rechnung kann nicht mehr geändert werden. Wenn die Rechnungen einmal in der Buchhaltung sind kann man nur noch Wert-Gutschriften schreiben.

Anderes Beispiel (mit dem ich zu tun habe)
In dem Projekt in dem ich arbeite werden Sendungen und Pakete verarbeitet. Es ist möglich eine Sendung zu öffnen auf on-hold zu setzen. In diesem Fall dürfen keine Pakete der Sendung mehr verladen werden. Parallel laufen im Lager die Arbeiter rum und scannen Pakete auf LKWs. BOOM

Sowas habe ich nicht. Beim Scannen der Pakete müsste eine Warnung kommen wenn eine Senung auf on-hold steht.

Kommt auch wieder drauf an. Bestellsystem, Kunde ruft an und gibt eine neue Adresse an die jetzt gerade angepasst wird. Parallel wird der Lieferschein für den Verlader ausgedruckt.

Wenn man bei mir den Lieferschein ändert, um z.B. eine neue Adresse / Lieferadresse / Einmal-Lieferadresse einzutragen, dann kann der Lieferschein nicht an anderer Stelle gedruckt werden. Es kommt dann eine Fehlermeldung.
Wenn der Lieferschein schon gedruckt wurde kann er nicht mehr so einfach geändert werden.
Wenn er doch geändert wurde muss er erneut gedruckt werden, wahlweise mit dem Aufdruck "Wiederholungsdruck, Lieferschein geändert", damit er nicht doppelt gepackt wird.

Ist schon alles irgendwie hinzukriegen. Aber wie Du gesagt hast "kommt immer drauf an ..."

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

1.564 Beiträge seit 2007
vor 14 Jahren

Hi Bernd!

Anderes Beispiel (mit dem ich zu tun habe)
In dem Projekt in dem ich arbeite werden Sendungen und Pakete verarbeitet. Es ist möglich eine Sendung zu öffnen auf on-hold zu setzen. In diesem Fall dürfen keine Pakete der Sendung mehr verladen werden. Parallel laufen im Lager die Arbeiter rum und scannen Pakete auf LKWs. BOOM

Sowas habe ich nicht. Beim Scannen der Pakete müsste eine Warnung kommen wenn eine Senung auf on-hold steht.

Das ist ja der Punkt. Die Sendung ist noch nicht auf On-Hold gesezt, soll das aber gerade werden. Das ist ja das Problem mit Gleichzeitigkeiten.

Kommt auch wieder drauf an. Bestellsystem, Kunde ruft an und gibt eine neue Adresse an die jetzt gerade angepasst wird. Parallel wird der Lieferschein für den Verlader ausgedruckt.

Wenn man bei mir den Lieferschein ändert, um z.B. eine neue Adresse / Lieferadresse / Einmal-Lieferadresse einzutragen, dann kann der Lieferschein nicht an anderer Stelle gedruckt werden. Es kommt dann eine Fehlermeldung.

Und damit hast du einen Read-Lock 😉

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

X
1.177 Beiträge seit 2006
vor 14 Jahren

huhu,

Gestern wollte ich noch schreiben, dass das schonmal vor 1 Jahr oder so lang diskutiert wurde, BerndFfm hat damals noch ausführlicher sein Schama erklärt. Es gab auch viele andere Entwürfe, Entscheidungshilfen etc.

Ich finde den Thread aber nicht mehr! Der war (in meiner Erinnerung) ziemlich gut. Einem Artikel/Faq-Eintrag fast würdig.

@BerndFfm: Kannst Du Dich noch erinnern?

BTW: Ich benutze derzeit extrem optimistisches Locking (last Change Wins - ohne Kompromisse) aber das liegt auch am Anwendungsfall und der benötigten Performance.

Um Konkreter zu werden: Es geht um Preise/Bestände, welche von Großhändlern geliefert werden. Diese werden nach Regeln vermixt und im Webshop dem Endkunden zur Verfügung gestellt. Hier prallen dann immer 2 Meinungen aufeinander:

a) Die Bestände und Preise müssen Echtzeit sein! (Die Verkäufer aus den Werbeagenturen)
b) So schnell kann keiner klicken. Selbst vor dem klick auf "Bestellen" kann der Bestand plötzlich auf 0 rutschen. (meine Meinung)

Deswegen werden die gelieferten Daten asynchron eingespielt: Erst wird alles in abzuarbeitende "Jobs" umgemünzt. Dann werden die Jobs nacheinander bearbeitet. Wenn eine Änderung den nächsten Shop (können kaskadiert sein) beeinflusst, dann gibts den nächsten Job. Damit halte ich die Load auf dem DB-Server auf einem kalkulierbaren Maß und habe trotzdem fast Echtzeit Preise/Bestände. Ein komplettes durchrechnen scheidet aus, da nicht vorhersagbar ist wieviele kaskadierende Shops es gibt und andererseits würde das evtl. die DB blockieren/ den Sever unter Vollast setzen (= Antwortzeiten werden ziemlich Mau).

Deswegen auch "extrem optimistischen locking". Alles überschreibt sich - was aber ja gewünscht ist.

😃

Xynratron

Herr, schmeiss Hirn vom Himmel - Autsch!

Die Erfahrung zeigt immer wieder, dass viele Probleme sich in Luft auslösen, wenn man sich den nötigen Abstand bzw. Schlaf gönnt.

3.825 Beiträge seit 2006
vor 14 Jahren

Hallo Xynratron,

Alles überschreibt sich

Das ist "absolutely no locking" !

Ja, an den langen Artikel erinnere ich mich auch. Da ging es um gewünschte Erweiterungen von ADO.NET. Mal suchen.

Ich mache das Update der Web-Shops auch mit Jobs, da macht es nix wenn der Shp mal nicht erreichbar ist 😉

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

R
Rocket Themenstarter:in
240 Beiträge seit 2007
vor 14 Jahren

Hallo Leute,

danke für die Infos. Sind sehr informativ und interressant mal zu hören wie andere das Problem lösen.
Ich denk ich werde mich für das optimistische Lock entscheiden, da nicht soviele User die Daten bearbeiten...
Diese Variante scheint ja auch den wenigsten Aufwand zu haben...

@Xynratron
Ich bin ja immer offen für neue Ideen.
Was genau meinst du mit Jobs, die nacheinander ablaufen?
Wie kann man sich das technisch vorstellen?

X
1.177 Beiträge seit 2006
vor 14 Jahren

Alles überschreibt sich

Das ist "absolutely no locking" !

NEEE, "extrem optimistisch 😜

Herr, schmeiss Hirn vom Himmel - Autsch!

Die Erfahrung zeigt immer wieder, dass viele Probleme sich in Luft auslösen, wenn man sich den nötigen Abstand bzw. Schlaf gönnt.