Fehler oder works as designed??
- Dieses Thema hat 7 Antworten und 1 Teilnehmer, und wurde zuletzt aktualisiert vor 14 Jahre, 6 Monaten von
Anonym.
-
AuthorPosts
-
2. Februar 2009 um 11:08 Uhr #4020
AnonymInaktivFolgende DDL:
C REATE TABLE DBA.CURSORTEST (FELD1 DEC(1), FELD2 DEC(1), FELD3 DEC(1))
IN DBA.TS;I NSERT INTO DBA.CURSORTEST VALUES (1, 1, 5);
I NSERT INTO DBA.CURSORTEST VALUES (1, 2, 5);
I NSERT INTO DBA.CURSORTEST VALUES (1, 3, 5);
I NSERT INTO DBA.CURSORTEST VALUES (1, 4, 5);C REATE UNIQUE INDEX DBA.XCURSORTEST ON DBA.CURSORTEST
(FELD1, FELD2, FELD3);folgende Logik im Programm:
D ECLARE C-UB CURSOR FOR
S ELECT FELD1, FELD2, FELD3
FROM DBA.CURSORTEST
WHERE FELD1 = :HF1
ORDER BY FELD2Zugriff über den Index…Es gibt im Explain keinen Sort-Step, daraus schliesse ich, dass die Ergebnismenge nicht "materialisiert" wird, sondern dynamisch nachgefetched wird.
Fetch erster Satz Into HF1, HF2, HF3, NOOP,
Fetch zweiter Satz Into HF1, HF2, HF3.Mit diesem HF3 := HF3 Minus! 1
U PDATE DBA.CURSORTEST
SET FELD3 = :HF3
WHERE FELD1 = :HF1
AND FELD2 = :HF2Fetch dritter Satz, NOOP
Fetch vierter Satz, NOOPalles ok
aber nun:
D ECLARE C-UB CURSOR FOR
S ELECT FELD1, FELD2, FELD3
FROM DBA.CURSORTEST
WHERE FELD1 = :HF1
ORDER BY FELD2Zugriff über den Index… Es gibt im Explain keinen Sort-Step, daraus schliesse ich, dass die Ergebnismenge nicht "materialisiert" wird, sondern dynamisch nachgefetched wird.
Fetch erster Satz Into HF1, HF2, HF3, NOOP,
Fetch zweiter Satz Into HF1, HF2, HF3.Mit diesem HF3 := HF3 plus! 1
U PDATE DBA.CURSORTEST
SET FELD3 = :HF3
WHERE FELD1 = :HF1
AND FELD2 = :HF2Fetch dritter Satz bringt den 2 (aktualisierten) Satz nochmal, NOOP
Fetch vierter Satz bringt den 3 Satz, NOOP
Fetch fünfter Satz bringt den 4 Satz, NOOPnormal?? OK, man könnte argumentieren, ich manipuliere mit meinem Update die Resultmenge und durch den dynamischen Fetch bekomme ich den wieder (aber warum? Den Satz hatte ich gerade und der Fetch soll mir den nächsten geben…)
Aber es kommt (m.E.) noch doller …
Ich lege den Index nur mit Feld1, Feld2 neu an, das Programm wird nur neu gebunden…D ECLARE C-UB CURSOR FOR
S ELECT FELD1, FELD2, FELD3
FROM DBA.CURSORTEST
WHERE FELD1 = :HF1
ORDER BY FELD2Zugriff über den Index…Es gibt im Explain auch hier keinen Sort-Step, daraus schliesse ich, dass die Ergebnismenge auch hier nicht "materialisiert" wird, sondern dynamisch nachgefetched wird.
Fetch erster Satz Into HF1, HF2, HF3, NOOP,
Fetch zweiter Satz Into HF1, HF2, HF3.Mit diesem HF3 := HF3 Plus!! 1
U PDATE DBA.CURSORTEST
SET FELD3 = :HF3
WHERE FELD1 = :HF1
AND FELD2 = :HF2
Fetch dritter Satz, NOOP
Fetch vierter Satz, NOOPalles ok … Warum bekomme ich hier nicht auch den aktualisierten Satz nochmal?
Ist das richtig/kann es richtig sein, dass das Ergebnis eines Programms vom Index-Design abhängig sein soll?Wir haben hier jetzt Grundsatzdiskussionen. Ähnliche Tests haben ergeben, dass das unter SQLServer2005 genauso läuft; unter Oracle wie von mir erwartet anders…
Was sagt ihr?
Danke
AlexanderPS: sorry für die Verstümmelung der SQLs, aber sonst wirds nicht gepostet …
2. Februar 2009 um 11:21 Uhr #4191
AnonymInaktivich habe alles mögliche ausprobiert in Sachen Isolation-Level bzw. CURRENT DATA. Das Verhalten bleibt.
Ich habe das (Fehl)Verhalten an die IBM gemeldet. Diese konnten es nachstellen (schon mal gut) und wollten weitere Infos.
Grüsse
Alexander
2. Februar 2009 um 12:07 Uhr #4319
AnonymInaktivHallo Alexander,
im letzten Fall müsstest du den neuen Wert meiner Meinung nach tatsächlich nochmal bekommen.
Ansonsten ist es so, das der Cursor und das Update-Stmt unabhängig voneinander sind. Beim Cursor hängt die Aktualität der Daten tatsächlich davon ab, ob materialisiert wird oder nicht (wobei DB2 immer versucht nicht zu materialisieren). Es wird durch das Locking lediglich sichergestellt, das die Daten zum Zeitupunkt des Zugriffs nicht von einer andereo UoW gesperrt waren (durch X-Lock).Wenn du immer das gleiche Ergebnis willst sollte Positioned Update statt Searched Update verwendet werden, also Cursor FOR UPDATE deklarieren und UPDATE … WHERE CURRENT OF….
Allerdings ist bei einem FOR UPDATE-Cursor keine ORDER-BY-Clause zulässig.
Und da schliesst sich der Kreis: Die Order-by-Clause ist nicht zulässig, da Materialisierung nicht ausgeschlossen werden kann, bzw. bei Materialisierung nach dem Open alle qualifizierten Rows mit U-Locks gesperrt wären.Es gibt mittlerweile die Möglichkeit einen Cursor als ASENSITIVE, INSENSITIVE oder SENSITIVE zu deklarieren (s. SQL-Ref., Declare Cursor), das könnte dein Problem lösen. Bitte schau dir das mal an, ich kann dir dazu leider nicht mehr sagen da ich damit noch nicht gearbeitet habe.
MfG Rolf
2. Februar 2009 um 13:01 Uhr #4411
AnonymInaktivHi Rolf,
was meinst Du mit "letztem" Fall? Meinen dritten mit dem IX ohne Feld3? Das wäre dann wenigstens konsequent.
Das was mich hier am meisten stört ist eben, dass je nach IX-Design (der Zugriff bleibt ja ohne Materialisierung) das Positionieren unterschiedlich geschieht.ich werde das Senistive mal schnell ausprobieren…
….
fertig!gibt ja beim DECLAR 5 Möglichkeiten:
– (nix=) NO SCROLL : Satz wird nochmal gefetched
– ASENSITIVE SCROLL: Satz wird nochmal gefetched
– INSENSITIVE SCROLL: Satz wird NICHT nochmal gefetched
– SENSITIVE (DYNAMIC) SCROLL: Satz wird nochmal gefetched
– INSENSITIVE STATIC SCROLL: Satz wird NICHT nochmal gefetchedok, danke für den Tipp!
Alexander
3. Februar 2009 um 7:34 Uhr #4472
AnonymInaktivDas Verhalten ist bekannt … war schon in der Version 1.x so.
( und war für mich sehr verwirrend damals )Wenn Du Feld3 nicht im Index hast, wird dieser Index durch den Update nicht verändert und DB2 positioniert auf den nächsten Satz.
Ist Feld3 im Index, wird durch den Update der Indexeintrag verändert und der "neue" Eintrag ist hinter der bisherigen Positionierung, so dass der Satz erneut gefunden wird.  "Neu" deshalb, weil jede Indexänderung ein D ELETE + I NSERT ist
3. Februar 2009 um 10:15 Uhr #4501
AnonymInaktivMoin,
Ulrich, das hört sich nachvollziehbar an (so ungern ich das als ehemaliger Entwickler auch zugebe).
Bei dem Gedanken, dass man als DBAdmin Programmläufe beeinflussen kann, wenn man aus Performancegründen einen Index anlegt, stellen sich bei mir die Nackenhhaare auf :-/Danke!
Alexander
4. Februar 2009 um 14:32 Uhr #4523
AnonymInaktivHallo Alexander,
mit dem letzten Fall meinte ich den, wo du die HV3 +1 veränderest und in FELD3 updatest.
Das Problem ist hier halt die Materialisierung (bzw. die nicht-Materialisierung).
Gefällt mir persönlich auch nicht, du kannst ja mal bei IBM ein PMR dafür aufmachen, dann wird man das Problem aber nur wortreich wegsprechen.
MfG Rolf
6. März 2009 um 12:44 Uhr #4536
AnonymInaktivHallo zusammen,
wir haben damit tatsächlich ein Problem aufgemacht. Leider kamen weder wortreiche noch hilfreiche Antworten (ich sollte mal mit RowSet arbeiten …). Ich hatte nicht den Eindruck, dass die sich wirklich ernsthaft damit beschäftigt haben 🙁
naja, Hauptsache, wir haben einen Workarround.
Grüsse
Alexander
-
AuthorPosts
You must be logged in to reply to this topic.