| 

.NET C# Java Javascript Exception

3
Hallo zusammen,

ich habe in VB.NET ein Tool geschrieben, das Daten aus einer Access-DB abfragt und jeweils einen Datensatz zur Korrektur in einem Formular anzeigt.

Da immer 5-10 Personen gleichzeitig daran arbeiten, muss ich sicherstellen, dass jeder User jeweils einen anderen Datensatz angezeigt bekommt. 'Gelöst' habe ich das so:

Reservieren eines Datensatzes:

UPDATE 
(SELECT TOP 1 * FROM Tabelle
WHERE (
Zustand = 'ToDo'
)
ORDER BY ID)
SET Zustand = 'Mein Name';


Anzeige des reservierten Datensatzes

SELECT * FROM Tabelle WHERE Zustand = 'Mein Name';


Mein Name ist hierbei der Inhalt einer Stringvariable, die den Namen des Users enthält.

Trotzdem kommt es immer wieder vor, dass 2 User denselben Datensatz bearbeiten, also das UPDATE erst ausgeführt wird, wenn der zweite User bereits die SELECT Unterabfrage gestellt hat.

Hat jemand eine Idee, wie ich das lösen kann?
17.09.2012
radelrutscher 11 3
2 Antworten
3
Versuch es mal in dem du das Transactions-Isolations-Level auf READ COMMITTED oder wohl besser noch auf SERIALIZABLE setzt.

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

oder

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

Optional auch in Kombination mit einer Transaktion:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION T1

UPDATE
(SELECT TOP 1 * FROM Tabelle
WHERE (
Zustand = 'ToDo'
)
ORDER BY ID)
SET Zustand = 'Mein Name';

IF (@@ERROR <> 0)
ROLLBACK TRANSACTION T1
ELSE
COMMIT TRANSACTION T1


Edit bezugnehmend auf deinen zweiten Post, mach es doch besser so:

UPDATE 
(SELECT TOP 1 * FROM Tabelle
WHERE (
Zustand = 'ToDo'
)
ORDER BY newid())
SET Zustand = 'Mein Name';

Durch newid() wird in diesem Fall eine zufällig GUID erzeugt.
17.09.2012
Floyd 14,6k 3 9
Floyd 14,6k 3 9
Alles klar, merci für deine Hilfe. Werd's morgen bei der Arbeit testen.
radelrutscher 17.09.2012
Sieht gut aus, danke für den Tipp.
Imm Beispiel (Access-DB) wäre das dann
ORDER BY Rnd(ID)
radelrutscher 18.09.2012
1
Hab mal irgendwo gelesen das es besser wäre eine negtaive Nummer als Startwerte für Rnd zu übergeben um "echte" Zufallszahlen zu erhalten. Rnd selbst erzeugt Zufallszahlen IMMER in einer festen Reihenfolge. Von daher funktioniert es so wie du es machst nicht richtig. Besser wäre:

Rnd(ID*Time())

oder

Rnd(-(1000*ID)*Time())
Floyd 18.09.2012
Das ist übrigens kein reines Access-Problem sondern betrifft viele Implementierungen einer Zufallsfunktion.
Floyd 18.09.2012
0
Habe es jetzt anders gelöst:

UPDATE ( 
SELECT TOP 1 *
FROM (
SELECT TOP MEINEID *
FROM (Tabelle)
WHERE (Zustand = 'ToDo')
ORDER BY StatusDatum, ID
)
ORDER BY ID DESC
)
SET Zustand = 'Mein Name'


MEINEID ist ein eindeutiger Integerwert, die Unterabfrage gibt also bei jedem User eine unterschiedliche Anzahl Datensätze aus. Durch die DESC Sortierung des oberen Subselects bekommt jeder User einen anderen Datensatz - hoffentlich :-)
18.09.2012
radelrutscher 11 3
Schau dir bitte noch den Edit von meinem Post an. Die Lösung ist etwas besser/robuster.
Floyd 18.09.2012

Stelle deine Sql-Frage jetzt!