2008-10-22 5 views

Antwort

8

Wenn Sie Oracle glauben, nein, überhaupt nicht. Das liegt daran, dass Oracle große Anstrengungen unternommen hat, um es zu vermeiden.

Das Problem ist, dass die Leser blockieren können, Autoren und Autoren blockieren Leser, und ein Schriftsteller muss warten, bis alle Leser mit einer Zeile fertig sind, bevor es schreiben kann. Das verzögert den Schreibvorgang und seinen Aufrufer. Exklusive Sperren (zum Schreiben) werden am Ende der Transaktion gehalten, für den Fall, dass die Transaktion zurückgesetzt werden muss - dies stoppt, dass andere Transaktionen den neuen Wert sehen, bis die Transaktion festgeschrieben wird.

In der Praxis ist das Sperren im Allgemeinen gut, wenn nicht zu viele Konflikte auftreten, wie bei jeder gleichzeitigen Programmierung. Wenn es zu viele Konflikte für eine Zeile/Seite/Tabelle gibt (nicht viele Datenbankserver sperren die gesamte Datenbank), führt dies dazu, dass die Transaktionen nacheinander und nicht gleichzeitig ausgeführt werden.

Oracle verwendet die Zeilenversionsverwaltung. Statt eine Zeile zu sperren, um sie zu schreiben, wird stattdessen eine neue Version der Zeile erstellt.Leser, die ihre Lesevorgänge wiederholen müssen, merken sich, welche Version der Zeile sie lesen. Ein Fehler tritt jedoch auf, wenn ein Leser, der sich an seine Lesevorgänge erinnert, versucht, eine Zeile zu aktualisieren, die von einem anderen Schreiber aktualisiert wurde, da diese Transaktion ihn gelesen hat. Dies ist, um verlorene Updates zu stoppen. Um sicherzustellen, dass Sie eine Zeile aktualisieren können, müssen Sie sagen, dass SELECT für UPDATE ist; Wenn Sie dies tun, dauert es eine Sperre - nur eine Transaktion kann eine Zeile für UPDATE zu einer Zeit enthalten, und eine in Konflikt stehende Transaktion muss warten.

SQL Server 2005 und höher unterstützen die Snapshot-Isolierung, was ihr Name für Zeilenversionsverwaltung ist. Auch hier sollten Sie nach Update-Sperren fragen, wenn Sie einige gerade gelesene Daten aktualisieren müssen - verwenden Sie in SQL Server WITH (UPDLOCK).

Ein weiteres Problem beim Sperren ist die Wahrscheinlichkeit von Deadlocks. Dies ist einfach, wenn zwei Transaktionen jeweils eine Sperre für eine Ressource halten, die die andere benötigt, oder im Allgemeinen ein Zyklus von Transaktionen Sperren hält, die sich gegenseitig fortführen müssen. Der Datenbankserver erkennt diesen Deadlock im Allgemeinen und beendet eine der Transaktionen, indem er sie zurücksetzt. Anschließend müssen Sie den Vorgang erneut versuchen. Jede Situation, in der Sie mehrere gleichzeitige Transaktionen haben, die dieselben Zeilen ändern, hat das Potenzial für Deadlock. Der Deadlock wird auftreten, wenn die Zeilen in einer anderen Reihenfolge berührt werden; Es ist sehr schwierig, die Reihenfolge zu erzwingen, die der Datenbankserver verwenden wird (im Allgemeinen sollte der Optimierer die schnellste Reihenfolge auswählen, die bei verschiedenen Abfragen nicht unbedingt konsistent ist).

Im Allgemeinen würde ich das gleiche wie mit Threading vorschlagen - gehen Sie mit Sperren, bis Sie beweisen können, dass sie ein Problem Skalierbarkeit verursachen, dann erarbeiten, wie Sie die wichtigsten Abschnitte sperren-frei machen.

1

Ich denke nicht, weil es den ganzen Weg "down" ist und Ihre Anwendung komplexer macht. Die meisten Sprachen verfügen über ausgezeichnete Techniken zur Handhabung des Parallelitätsverhaltens, und selbst dann ist der beste Weg, Code zu schreiben, der die Nebenläufigkeit "nativ" handhaben kann.

Für weitere Informationen über die Parallelität in Java: http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html

+0

Code, der Gleichzeitigkeit "nativ" behandeln kann ... irgendeinen Vorschlag wie? – Graviton

+0

Ich denke, er meint die Verwendung der Funktionen der Programmiersprache oder Bibliothek wie java.util.concurrent. –

+0

Ja. Siehe auch http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html – Rolf

0

Meinen Sie Parallelität in Ihrer Anwendung zu behandeln, oder ein Concurrency Problem lösen Sie mit der Datenbank haben. Wenn der erste, es scheint mir nicht als ein guter Ansatz. Wenn Letzteres der Fall ist, kann dies Ihre einzige Antwort sein, ohne Ihre Schemas neu zu entwickeln.

1

Das Sperren von Datenbanken - im Gegensatz zum Sperren von Tabellen oder Zeilen - ist eine schlechte Methode, mit Nebenläufigkeit umzugehen; es schließt Nebenläufigkeit aus.

+0

Könnten Sie Ihre Antwort näher erläutern? Es ist eine schlechte Art, damit umzugehen, weil es es verhindert? – DOK

+0

Ich denke, sein Punkt ist, Sie sperren die Datenbank, Sie haben keine Nebenläufigkeit, wie es gesperrt ist. –

+0

@ dok1: Mitchel hat es richtig gemacht. Wenn Sie die Datenbank sperren (im exklusiven Modus), gibt es überhaupt keinen gleichzeitigen Zugriff. Wenn Sie eine Datenbank im schreibgeschützten Modus sperren, können mehrere Personen die Datenbank lesen, aber niemand kann sie ändern. (Ich kenne ein DBMS, das exklusive Sperren für Datenbanken zur Verfügung stellt.) –

2

Sie müssen zuerst Ihr Ziel definieren. Bei gleichzeitiger Anfrage möchten Sie den letzten Benutzer oder den ersten Benutzer gewinnen. Datenbank sperren ist sicherlich eine schlechte Möglichkeit. Versuchen Sie, die Tabelle/Zeilen so spät wie möglich zu sperren und sperren Sie so schnell wie möglich.

1

Es gibt viele sinnvolle Alternative, um DMBS-Sperren von irgendeiner Art zu codieren. Denken Sie daran, dass eine Art Locking wirklich immer passiert (atomare Aktionen, etc), aber der Schlüssel ist, dass Sie nicht dorthin gehen wollen, wenn Sie nicht müssen. Sie wollen nicht mit Philosophen essen, wenn Sie nicht müssen. Transaktionen sind eine Möglichkeit, Locking zu umgehen, aber das ist meistens für Commits. Wenn Sie ein Feld verwenden, das den Datensatz markiert/anzeigt, ist das (Dirty bit pattern) eine andere Möglichkeit, stellen Sie sicher, dass Sie dies auf atomare Weise tun. Die Sprache hat oft eine geeignete Lösung, auf die in früheren Beiträgen verwiesen wird, die Sprache unterstützt jedoch normalerweise nur die Anwendung, den Prozess zur Verarbeitung, die Nebenläufigkeit der Ebene und manchmal die Parallelität muss in der Datenbank sein. Ich wollte nicht annehmen, dass Sie eine reichhaltige Anwendungsschicht haben, aber wenn Sie das tun, gibt es viele Abstraktionsschichten, die das für Sie erledigen. TopLink by Oracle ist kostenlos und ist der robustere Bruder von Hibernate. Beide unterstützen Sie bei der Bewältigung Ihrer Datenbankkonkurrenzen durch Abstraktion, Dirty-Bits, Caching und Lazy Locking. Sie möchten diese selbst nicht implementieren, es sei denn, Sie programmieren für ein Schul- oder persönliches Projekt. Verstehen Sie das Problem, aber stehen Sie auf den Schultern von Riesen.