ďťż
 
DB2 - pobieranie wyniku z SELECT'a ďťż
 
DB2 - pobieranie wyniku z SELECT'a
Zobacz wiadomości
 
Cytat
A gdyby tak się wedrzeć na umysłów górę, / Gdyby stanąć na ludzkich myśli piramidzie, / I przebić czołem przesądów chmurę, / I być najwyższą myślą wcieloną. . . Juliusz Słowacki, Kordian
Indeks BCB i MySQL subiekt gt fototapeta
 
  Witamy

DB2 - pobieranie wyniku z SELECT'a



Kolszew - 28-08-2007 00:08
DB2 - pobieranie wyniku z SELECT'a
  Zaczynam dopiero z DB2 LUW ...

Mam problem.
Jeżeli ktoś zmodyfikuje wiersz i nie zakończy transakcji to
na innym stanowisku zapytanie SELECT pobierające listę
z tej tabeli na ekran (do przeglądania) blokuje się (czeka).
Chodzi to jak mniemam o blokadę wiersza która uniemożliwia
założenie blokady "shared" wymaganej do odczytania wiersza
przy domyślnym poziomie separacji transakcji.

Czy nie da się tego ominąć? Czy czytane danych tylko do
przeglądania nie może nie zakładać blokady "shared"?
Słyszałem coś o kursorach "readonly", jak zrobić aby
aplikacja w Javie (via JDBC) otwierała takie kursory dla
ResultSet'ów?

Pozdro
Krzysiek





Artur - 28-08-2007 00:08

  On Aug 27, 1:04 pm, Kolszew
<WYTNIJTOkrzysiekWYTNIJTO...@stream.com.pl> wrote:
> Zaczynam dopiero z DB2 LUW ...
>
> Mam problem.
> Jeżeli ktoś zmodyfikuje wiersz i nie zakończy transakcji to
> na innym stanowisku zapytanie SELECT pobierające listę
> z tej tabeli na ekran (do przeglądania) blokuje się (czeka).
> Chodzi to jak mniemam o blokadę wiersza która uniemożliwia
> założenie blokady "shared" wymaganej do odczytania wiersza
> przy domyślnym poziomie separacji transakcji.
>
> Czy nie da się tego ominąć? Czy czytane danych tylko do
> przeglądania nie może nie zakładać blokady "shared"?
> Słyszałem coś o kursorach "readonly", jak zrobić aby
> aplikacja w Javie (via JDBC) otwierała takie kursory dla
> ResultSet'ów?
>
> Pozdro
> Krzysiek

Blokady zakładane są po to by odczytać spójne dane -- zapytanie czeka
na zatwierdzenie lub wycofanie zmian.

Jeśli nie chcesz czekać na blokady, wtedy możesz przeczytać aktualną
zawartość poprzez poziom izolacji uncommited read -- ale czytanie
niezatwierdzonych danych nie zawsze jest dobrym rozwiązaniem. Poziom
izolacji możesz określić na poziomie danego zapytania SQL lub jako
parametr połączenia.

W DB2 powinno się projektować aplikacje tak, by modyfikacje były
wysyłane do bazy danych jako paczka. Np. kiepskim rozwiązaniem jest
modyfikowanie części danych (transakcja rozpoczęta), a potem
oczekiwanie na dalsze decyzje użytkownika. DB2 w miarę dobrze będzie
kolejkowało żądania do danych, więc ewentualne zapytania przy takiej
organizacji nie będą wstrzymywane zbyt długo (milisekundy).

Ogólnie spójność danych jest jednym z poważniejszych zagadnień,jakie
powinien zaadresować twórca aplikacji. Zwykle w przypadku aplikacji
bazodanowych chcemy czytać spójne dane (spójny odczyt), ale także
chcemy odczytane dane potem wykorzystać do dalszych modyfikacji
(spójny zapis). Np. jeśli pan X wypłaca pieniądze z konta, to jego
żona robiąc to samo chwilę później z innej części kraju poczeka by
dowiedzieć się, ile zostało po operacji, ponieważ na tej podstawie
zwykle podejmuje decyzję "ile wypłacić".

W DB2 masz do dyspozycji:
-- poziomy izolacji ANSI pozwalające na zablokowanie odczytanych
danych (w trybie do odczytu bądź na wyłączność), tak by możnabyło
potem zrobić odpowiednie modyfikacje
-- poziomy izolacji możesz ustawić na poziomie danego zapytania, sesji
bądź programu (tu: pakietu).
-- masz do dyspozycji specjalne zmienne rejestrowe, które zmieniają
zachowanie poziomów izolacji ANSI (DB2_SKIPINSERTED, DB2_SKIPDELETED,
DB2_EVALUNCOMMITTED)
-- w 9.5 (jeśli dopiero tworzysz aplikację) masz do dyspozycji, tzw.
optymistyczne blokowanie rekordów (czytasz zestaw rekordów;
przetwarzasz w aplikacji; i dopiero w momencie modyfikacji sprawdzasz,
czy ktoś w międzyczasie nie zmienił zestawu rekordów -- jeśli tak
musisz powtórzyć operację).
-- masz też do dyspozycji tzw. selekt z insert, delete lub update,
które pozwolą ci spójnie zrobić jakąś operację w jednym kroku.. Np.
instrukcja poniżej usuwa z tabeli rekord, który jest najstarszy a
następnie zwraca usunięty rekord do aplikacji (zamiast 3 instrukcji,
tylko 1):

SELECT ordernum, ... INTO :ordernum, ...
FROM OLD TABLE(DELETE
FROM (SELECT * FROM orders
ORDER BY ordernum
FETCH FIRST ROW ONLY));

Ogólnie najlepiej tak projektować aplikacje, by różni użytkownicyjak
najmniej pracowali na tych samych zestawach danych w tym czasie (ważne
są kryteria wyszukiwania oraz indeksy).

-- Artur Wroński

Link do dokumentacji 9.5 (poszukaj, isolation level, optimistic
locking):
https://publib.boulder.ibm.com/infoc.../starthere.htm




Kolszew - 29-08-2007 00:11

  > Blokady zakładane są po to by odczytać spójne dane -- zapytanie czeka
> na zatwierdzenie lub wycofanie zmian.
>
> Jeśli nie chcesz czekać na blokady, wtedy możesz przeczytać aktualną
> zawartość poprzez poziom izolacji uncommited read -- ale czytanie
> niezatwierdzonych danych nie zawsze jest dobrym rozwiązaniem. Poziom
> izolacji możesz określić na poziomie danego zapytania SQL lub jako
> parametr połączenia.
>
>

Dzięki. Rozumiem kwestię i sprawa dla mnie jest dosyć jasna,
przy przetwarzaniu danych jak najbardziej oczekiwany jest spójny
obraz bazy, więc blokady są jak najbardziej ok.
Chodzi mi natomiast o taki banalny aspekt aplikacji jak tabelki (np.
JTable) z danymi które służą do przeglądania danych (są read only) na
ekranie. Ktoś przeglądający listę towarów ich, nazwy, cechy, stany nie
ma potrzeby aby czekał aż ktoś inny zakończy transakcję sprzedaży
zmniejszającą stan jednego z towarów,
bo i tak dane w tej tabeli (ekran) pochodzą z momentu zapytania do bazy
czyli z definicji po chwili są nieaktualne. Problem ten rozwiązuje
poziom transakcji ReadComited dostępnym w innych RDBMS'ach w DB2 go nie ma.

Znalazłem Twoją odpowiedź na jeden w wcześniejszych postów,
cytuję:

"W domyślnym poziomie izolacji (cursor stability) utrzymywana jest
blokada SHARED na wierszu, który aktualnie jest przetwarzany. SHARED,
tzn. inni nie mogą zmienić wiersza, ale mogą go zobaczyć. Przy czym
taka blokada jest zakładana jeśli kursor jest for UPDATE. Jeśli kursor
jest FOR READ ONLY, wtedy tak naprawdę pracuje się na kopii danych."

jak dobrze rozumiem to dla kursorów ReadOnly nie zakładana jest blokada
SHARED, czyli można czytać wiersze zmodyfikowane w niezatwierdzonych
jeszcze transakcjach, dobrze myślę?

Krzysiek




Artur - 29-08-2007 00:11

  On Aug 28, 1:55 pm, Kolszew
<WYTNIJTOkrzysiekWYTNIJTO...@stream.com.pl> wrote:
> > Blokady zakładane są po to by odczytać spójne dane -- zapytanieczeka
> > na zatwierdzenie lub wycofanie zmian.
>
> > Jeśli nie chcesz czekać na blokady, wtedy możesz przeczytać aktualną
> > zawartość poprzez poziom izolacji uncommited read -- ale czytanie
> > niezatwierdzonych danych nie zawsze jest dobrym rozwiązaniem. Poziom
> > izolacji możesz określić na poziomie danego zapytania SQL lub jako
> > parametr połączenia.
>
> Dzięki. Rozumiem kwestię i sprawa dla mnie jest dosyć jasna,
> przy przetwarzaniu danych jak najbardziej oczekiwany jest spójny
> obraz bazy, więc blokady są jak najbardziej ok.
> Chodzi mi natomiast o taki banalny aspekt aplikacji jak tabelki (np.
> JTable) z danymi które służą do przeglądania danych (są read only) na
> ekranie. Ktoś przeglądający listę towarów ich, nazwy, cechy, stany nie
> ma potrzeby aby czekał aż ktoś inny zakończy transakcję sprzedaży
> zmniejszającą stan jednego z towarów,
> bo i tak dane w tej tabeli (ekran) pochodzą z momentu zapytania do bazy
> czyli z definicji po chwili są nieaktualne. Problem ten rozwiązuje
> poziom transakcji ReadComited dostępnym w innych RDBMS'ach w DB2 go niema.
>
> Znalazłem Twoją odpowiedź na jeden w wcześniejszych postów,
> cytuję:
>
> "W domyślnym poziomie izolacji (cursor stability) utrzymywana jest
> blokada SHARED na wierszu, który aktualnie jest przetwarzany. SHARED,
> tzn. inni nie mogą zmienić wiersza, ale mogą go zobaczyć. Przy czym
> taka blokada jest zakładana jeśli kursor jest for UPDATE. Jeśli kursor
> jest FOR READ ONLY, wtedy tak naprawdę pracuje się na kopii danych."
>
> jak dobrze rozumiem to dla kursorów ReadOnly nie zakładana jest blokada
> SHARED, czyli można czytać wiersze zmodyfikowane w niezatwierdzonych
> jeszcze transakcjach, dobrze myślę?
>
> Krzysiek

W DB2 nie ma poziomu izolacji Read Commited.

Opisywany przeze mnie fragment dotyczy sytuacji, gdy ktoś czyta
kursorem tabelę w trybie Cursor Stability. Jeśli zapytanie jest typu
Read Only, to wtedy mimo odczytania rekordu i spozycjonowaniu kursora
na tym rekordzie inni użytkownicy będą mogli zmodyfikować dokładni ten
sam rekord. Natomiast jeśli już ktoś inny już go zmodyfikował a my
potem zabieramy się za czytanie rekordów (inna kolejność), to w tym
poziomie izolacji trzeba będzie poczekać na zatwierdzenie transakcji
modyfikującej rekord.

[Tak na marginesie, jeśli kursor nie byłby For Read Only wtedy po
odczytaniu rekordu, bieżący, przetwarzany rekord nie może być
zmodyfikowany przez innych, ze względu na blokadę shared]

Jeśli modyfikacje wystartowane przed uruchomieniem selekta są
krótkie, to opóźnienie w selekcie nie będzie większe niż przy
wykonywaniu zapytania w trybie Read Commited, który musi wykonać
trochę pracy związanej z wersjonowaniem rekordu.

Jeśli przewidujesz długie transakcje a nie interesuje Cię dokładna
wartość, wtedy możesz zastosować tryb uncommited read -- oczywiście
czytasz dane niezatwierdzone, ale w opisanym przez Ciebie przypadku i
tak to nie ma większego znaczenia.

-- Artur Wroński





Kolszew - 30-08-2007 00:01

  > W DB2 nie ma poziomu izolacji Read Commited.
>
> Opisywany przeze mnie fragment dotyczy sytuacji, gdy ktoś czyta
> kursorem tabelę w trybie Cursor Stability. Jeśli zapytanie jest typu
> Read Only, to wtedy mimo odczytania rekordu i spozycjonowaniu kursora
> na tym rekordzie inni użytkownicy będą mogli zmodyfikować dokładni ten
> sam rekord. Natomiast jeśli już ktoś inny już go zmodyfikował a my
> potem zabieramy się za czytanie rekordów (inna kolejność), to w tym
> poziomie izolacji trzeba będzie poczekać na zatwierdzenie transakcji
> modyfikującej rekord.
>
> [Tak na marginesie, jeśli kursor nie byłby For Read Only wtedy po
> odczytaniu rekordu, bieżący, przetwarzany rekord nie może być
> zmodyfikowany przez innych, ze względu na blokadę shared]
>
> Jeśli modyfikacje wystartowane przed uruchomieniem selekta są
> krótkie, to opóźnienie w selekcie nie będzie większe niż przy
> wykonywaniu zapytania w trybie Read Commited, który musi wykonać
> trochę pracy związanej z wersjonowaniem rekordu.
>
> Jeśli przewidujesz długie transakcje a nie interesuje Cię dokładna
> wartość, wtedy możesz zastosować tryb uncommited read -- oczywiście
> czytasz dane niezatwierdzone, ale w opisanym przez Ciebie przypadku i
> tak to nie ma większego znaczenia.
>
> -- Artur Wroński

Dzięki za szczegółowe wyjaśnienia.
Ostatnie pytanie, czy w DB2 nie jest planowany jakiś mechanizm
który zrekompensował by brak ReadComited? Czy ten brak w
praktyce jest w ogóle dotkliwy, czytałem kilka razy posty osób
opisujących problemy lawinowego przyrostu blokad w DB2, czytałem
też artykuł gościa z ORACLE'a który jawnie określił sposób
blokowania w DB2 jako największą wadę tej bazy.

Krzysiek.




Artur - 01-09-2007 00:17

  On Aug 29, 10:20 am, Kolszew
<WYTNIJTOkrzysiekWYTNIJTO...@stream.com.pl> wrote:
> > W DB2 nie ma poziomu izolacji Read Commited.
>
> > Opisywany przeze mnie fragment dotyczy sytuacji, gdy ktoś czyta
> > kursorem tabelę w trybie Cursor Stability. Jeśli zapytanie jest typu
> > Read Only, to wtedy mimo odczytania rekordu i spozycjonowaniu kursora
> > na tym rekordzie inni użytkownicy będą mogli zmodyfikować dokładni ten
> > sam rekord. Natomiast jeśli już ktoś inny już go zmodyfikowała my
> > potem zabieramy się za czytanie rekordów (inna kolejność), to wtym
> > poziomie izolacji trzeba będzie poczekać na zatwierdzenie transakcji
> > modyfikującej rekord.
>
> > [Tak na marginesie, jeśli kursor nie byłby For Read Only wtedy po
> > odczytaniu rekordu, bieżący, przetwarzany rekord nie może być
> > zmodyfikowany przez innych, ze względu na blokadę shared]
>
> > Jeśli modyfikacje wystartowane przed uruchomieniem selekta są
> > krótkie, to opóźnienie w selekcie nie będzie większe niż przy
> > wykonywaniu zapytania w trybie Read Commited, który musi wykonać
> > trochę pracy związanej z wersjonowaniem rekordu.
>
> > Jeśli przewidujesz długie transakcje a nie interesuje Cię dokładna
> > wartość, wtedy możesz zastosować tryb uncommited read -- oczywiście
> > czytasz dane niezatwierdzone, ale w opisanym przez Ciebie przypadku i
> > tak to nie ma większego znaczenia.
>
> > -- Artur Wroński
>
> Dzięki za szczegółowe wyjaśnienia.
> Ostatnie pytanie, czy w DB2 nie jest planowany jakiś mechanizm
> który zrekompensował by brak ReadComited? Czy ten brak w
> praktyce jest w ogóle dotkliwy, czytałem kilka razy posty osób
> opisujących problemy lawinowego przyrostu blokad w DB2, czytałem
> też artykuł gościa z ORACLE'a który jawnie określił sposób
> blokowania w DB2 jako największą wadę tej bazy.
>
> Krzysiek.

W praktyce sposób blokowania nie jest problem. Oczywiście trzeba być
świadomym faktu, że blokowanie ogranicza dostępność i dlatego
transakcje powinny być możliwie krótkie. Przy czym tak naprawdę wiele
osób pisze aplikacje na żywioł, nie zastanawiając się nad tym, jak
chcą obsłużyć przypadki, gdy wielu użytkowników chce pracowaćna tych
samych danych. W przypadku Oracle, mamy możliwość czytania starej
wersji danych, nie mamy problemów z oczekiwaniem na blokady przy
zapytaniach, ale nieprzemyślane użycie tego poziomu izolacji może
doprowadzać do niespójności przy zapisie danych. Przykład: w systemach
transakcyjnych, zwykle czyta się dane po to, by potem na podstawie
odczytanych wartości wykonać odpowiedni zapis. Wielu deweloperów, z
którym rozmawiałem tworzą aplikację pod Oracle wykorzystując blokady
dokładnie w taki sam sposób jak w DB2. Czytasz blokując jednocześnie
do zapisu, zapisujesz, zwalniasz blokady.

Zwróć też uwagę, że wersjonowanie rekordów jest stosunkowo kosztowną
operacją. W efekcie finalnym zapytanie oczekujące na zakończenie
update, niekoniecznie wykona się dłużej niż zapytanie które nie
oczekuje, ale baza zajęta jest przygotowywaniem starej wersji rekordu
(może zły przykład, ale weź kopiowanie dwóch plik z dysku na dysk.
Jeśli to oba pliki zaczniesz kopiować w tym samym czasie, masz
wrażenie, że wszystko dzieje się współbieżnie, ale w praktyce byłoby
dużo szybciej, by system zaczął kopiować pierwszy plik (drugi czekaw
kolejce) a potem drugi).

Co do "rekompensaty" to mogę tylko powtórzyć, to co już napisałem.
Zmienne DB2_SKIPINSERTED, DB2_SKIPDELETED, DB2_EVALUNCOMMITTED
pozwalają nie oczekiwać na blokady (dla poziomy izolacji Cursor
Stability) dla rekordów wstawionych bądź usuniętych (są niewidoczne
dla drugiej sesji). DB2_EVALUNCOMMITTED pozwala ci zignorować
zablokowany wiersz, jeśli dane w środku wiersza nie pasują do twojego
kryterium wyszukiwania.

Innymi technikami jest optymistyczny sposób blokowania danych dostępny
w DB2 9.5 oraz delete z selekta, selekt z delete, update, insert. W
jednym kroku czytasz i zmieniasz rekordy (albo zmieniasz i zwracasz to
co było zmienione), np zobacz na to:

SELECT ordernum, ... INTO :ordernum, ...
FROM OLD TABLE(DELETE
FROM (SELECT * FROM orders
ORDER BY ordernum
FETCH FIRST ROW ONLY));

Pewnie w przyszłości także pojawi się taki poziom izolacji (2008?),
ale jak powiedziałem w praktyce nie jest to problemem (patrz testy
wydajnościowe TPC, czy testy aplikacji SAP -- produkcyjne i
laboratoryjne. Wypadają bardzo dobrze na tle Oracle).

-- Artur




Kolszew - 06-09-2007 00:04

  >
> Pewnie w przyszłości także pojawi się taki poziom izolacji (2008?),
> ale jak powiedziałem w praktyce nie jest to problemem (patrz testy
> wydajnościowe TPC, czy testy aplikacji SAP -- produkcyjne i
> laboratoryjne. Wypadają bardzo dobrze na tle Oracle).
>

Dzięki.

Krzysiek

PS
Twoje posty w tym wątku to jedne z najlepszych merytorycznie odpowiedzi
jakie widziałem na tej liście.
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • effulla.pev.pl
  • comp
    [help] Illustrator CS - =?ISO-8859-2?Q?znikn=B1=B3_Selection_?==?ISO-8859-2?Q?Tool_=28V=29?= [mysql 4.0] SELECT t1.id, t1.foo FROM t1 oraz COUNT t2 w jednym zapytaniu. SELECT MAX(nazwaPola) FROM tabela WHERE .... i ORA-01405: pobran? warto?ci? kolumny jest NULL =?iso-8859-2?q?select_sum_i_dwie_tabele..._b=B3=EAdna_agregac ja?= =?iso-8859-2?Q?=5BMySql=5D_-_select_po_5_rekordow_mniejssych_i_wi=EAkszych?= =?iso-8859-2?Q?=5BMySql=5D_Select_wed=B3ug_nazwy_pola?= =?ISO-8859-2?Q?[mysql]_Nie_potrafi=EA_zgrupowa=E6_selecta_(proste)?= =?ISO-8859-2?Q?[MS_SQL]_update_wielu_p=F3l_na_raz_z_selecta?= Wstawianie nowego wiersza w przypadku jego braku podczas SELECT w PostgreSQL [pgsql] jak =?ISO-8859-2?Q?zrobi=E6_taki_select_=3F?=
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • fantazia.htw.pl
  • Cytat

    Decede mihi sole - nie zasłaniaj mi słonca.
    Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści
    Hoc fac - tak czyń.
    A tergo - od tyłu; z tyłu.
    I czarne włosy posiwieją. Safona

    Valid HTML 4.01 Transitional

    Free website template provided by freeweblooks.com