Czy jest mozliwosc zrobienia transakcji ktora nie blokuje calej tabeli, a
jedynie wiersz ktory jest edytowany albo insertowany. Jak rozwiazuje sie
problem kiedy kilku uzytkownikow dziala na tej samej tabeli i blokuja sie
nawzajem.
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
--
wloochacz
Z tego co wiem to podczas otwarcia transakcji nie blokuje się dostępu do
tabeli,
inni użytkownicy mogą z tej tabeli korzystać, poprzez select, insert i
update.
Transakcja ma na celu potwierdzenie dodkonanych zmian (commit) lub ich
cofnięcie (rollback) np w przypadku
warunku: wykonane zostaną wszystkie zmiany albo żadna np ze względu na
wystąpienie błędu w programie.
Tranakcja może czasami zajmować dość dużo czasu (wiele zapytań i zmian) w
rozbudowanych bazach więc blokowanie ogólnie dostępu było by tu niewskazane.
Jeżeli zachodzi potrzeba zablokowania danego rekordu ze względu na możliwość
odczytania prze innych użytkowników niejednolotych danych najlepiej te
newralgiczne zmiany zablokować programowo.
Adam
> Tranakcja może czasami zajmować dość dużo czasu (wiele zapytań i zmian) w
> rozbudowanych bazach więc blokowanie ogólnie dostępu było by tu niewskazane.
Nie chodzi o blokowanie "ogólnego dostępu" - chodzi o blokowanie
konkretnego wiersza w konkretnej tabeli.
To prawda że blokowanie jest zazwyczaj kosztowną operacją, ale
stosunkowo łatwo można oprogramować z góry określoną ilość blokad. A co
za tym idzie szanować zasoby serwera. Tylko, tak naprawdę, taki problem
zaistnieje przy na prawdę duuużej ilości blokad.
> Jeżeli zachodzi potrzeba zablokowania danego rekordu ze względu na możliwość
> odczytania prze innych użytkowników niejednolotych danych najlepiej te
> newralgiczne zmiany zablokować programowo.
A dlaczego się męczyć, skoro załatwia to za nas baza danych?
--
wloocchacz
Dlaczego się męczyć............ już odpowiadam.
Programowo można wykluczyć taką sytuację:
1.Pobranie wartości z rekordu tabeli A
2.Start Transakcja
3.Obliczenia
4.Modyfikacja pobranego rekordu z tabeli A
5.ExecSQL (teraz zależy co się dzieje od ACID - read uncommitted, read
committed, repeatable read, serializable)
6.Modyfikacja rekordu w tabeli B na podstawie danych pobranych wcześniej z
Tabeli A
7.ExecSQL
8.Koniec transakcji (commited lub rollback).
............. i teraz zakładamy po pkt. 5 pobranie przez drugiego
użytkownika wartości rekordu Tabeli A i błąd po pkt 7 powodujący powrót do
stanu pierwotnego rekordu Tabeli A lub brak błędu i zapisane nowej wartości
rekordu w Tabeli A.
I teraz jak to zrobić z poziomu bazy aby ten drugi uzytkownik miał zawsze
aktualną wartość niezależnie czy po pkt 7 użytkownik 1 ma commit czy
rollback???
Ja zawsze rozwiązuję to programowo blokując dostęp do rekordu dopuki
użytkownik 1 nie zakończy tranakcji............. może jest jakieś 100%
rozwiązanie z poziomu bazy danych. ???
--
wloochacz
OK, OK......... przetestuję to sobie tylko napisz mi proszę jak zakłada się
taką blokadę na rekord w FireBird lub InterBase.
Jak to praktycznie dobrze zrobić.
Adam
Np. tak:
UPDATE tabela SET id = id;
gdzie id to pole będące kluczem głównym tej tabeli.
Od wersji 2.0 (nie jestem pewny) można jeszcze użyć
select x from y with lock
albo coś w ten deseń - doczytaj w dokumentacji.
--
Tomek Dzięcioł
A gdzie jest zakladana ta blokada??
Adam
>> jak zakłada się taką blokadę na rekord w FireBird lub InterBase.
>
> Np. tak:
> UPDATE tabela SET id = id;
hehehe :)
--
Pozdrawiam
Morff
--------------------
AQQ : 141151 (mo...@aqq.eu)
Poprawka
UPDATE tabela SET id = id WHERE id = :id;
>>
>> gdzie id to pole będące kluczem głównym tej tabeli.
>>
>> Od wersji 2.0 (nie jestem pewny) można jeszcze użyć
>> select x from y with lock
>> albo coś w ten deseń - doczytaj w dokumentacji.
>
> A gdzie jest zakladana ta blokada??
Wykonanie update na rekordzie blokuje rekord do edycji przez innych
użytkowników. Reszta uzależniona jest od poziomu izolacji transakcji.
--
Tomek Dzięcioł
--
wloochacz
--
wloochacz
> [ciach]
>>> Np. tak:
>>> UPDATE tabela SET id = id;
>> hehehe :)
> Co się cieszy - to jest tzw. pusty update :)
>
na rekordzie ?
--
wloochacz
Masz rację. Jakoś dzisiaj ma problem z formułowaniem wypowiedzi (patrz
update po całej tabeli).
--
Tomek Dzięcioł
No niewiem czy nie przekombinowaliście, przecież chodzi tylko o to by dwaj
uzytkownicy /czytaj dwie transakcje/ nie dokonywały w tym samym czacie zmian
w rekordzie jednym i tylko jednym a nie na całej tabeli.
To czy w tym samym czasie na rekordzie 10 i rekordzie 122 jest dokonywana
zmiana to dla oznaczonosci stanów tabeli nie ma znaczenia natomiast gdy by
chcieć w tym samym czasie dokonywac zmian na rekordzie np. 13 przez dwie
transakcje to jest problem który z userów czytaj transakcji jest wazniejsza.
a przez to ma piereszeństwo w realizacji. Głownym celem wprowadzenia
transakcji była zasada robimy wszytko albo nic dopiero przy okazji niejako
wyszła sprawa mozliwosci blokowania zmian na tych samych rekordach. Choć
niektórzy rozwiazali to po przez piorytety. Reasumując, otwieramy transakcję
by nie dac mozliwości innym dokonywania zmian w tym samym czasie i
natychmiast zamykamy transakcje by te zmiany innym umozliwić... to tak na
moje chłopskie zrozumienie sprawy. Więc jak czytam o mozliwości blokowaniu
całych tabel to się pytam ..po co to ?
pozdrawiam
jasiek
> Reasumuj�c, otwieramy transakcj�
> by nie dac mozliwo�ci innym dokonywania zmian w tym samym czasie i
> natychmiast zamykamy transakcje by te zmiany innym umozliwiďż˝... to tak na
> moje ch�opskie zrozumienie sprawy. Wi�c jak czytam o mozliwo�ci blokowaniu
> ca�ych tabel to si� pytam ..po co to ?
No to przeczytaj jeszcze raz.
I jeszcze raz.
A na ko�cu mo�e zrozumiesz, �e kolega Tomasz si� pomyli�, pisz�c
przyk�adowy kod SQL, co zauwa�y� Morff, a czego ja nie zauwa�y�em.
Poza tym nikt nie pisaďż˝ o blokowaniu tabel sensu stricte, tylko o
b��dnym UPDATE Tomasza, kt�re w efekcie zablokuje wszystkie rekordy w
tabeli.
I nie CA�� tabel�, bo np. nadal b�dzie mo�na dopisywa� do niej rekordy.
--
wloochacz
> A na końcu może zrozumiesz, że kolega Tomasz się pomylił, pisząc
> przykładowy kod SQL, co zauważył Morff, a czego ja nie zauważyłem.
> Poza tym nikt nie pisał o blokowaniu tabel sensu stricte, tylko o błędnym
> UPDATE Tomasza, które w efekcie zablokuje wszystkie rekordy w tabeli.
> I nie CAŁĄ tabelę, bo np. nadal będzie można dopisywać do niej rekordy.
masz rację moja pomyłka ale to nie zmienia wymowy wywodu jezeli blokujemy
wybrany rekord na czas edycji to czym żesz to jest, jak nie zdublowaniem tej
samej operacji. W pierwszym kroku blokujemy po przez wykonanie update które
nic w sumie nie robi samo siebie zmienia i to na kluczu ID /jezeli to jest
klucz/ a w drugim etapie dokonujemy zmiany na powiedzmy 3 polu tabeli i
konczymy transakcje / tak sie domyslam/ więc po grzyba wykonywac ta pierwszą
operacje ? Kiedy otworzenie dla tej drugiej operacji transakcji wykona to
samo: uniemozliwi innemu userowi zmian w updatowanym rekordzie :(.
Strata czasu, obciazenie łacza, a i mozliwośc przypału ...user wszedł se do
tabeli rozpoczoł zmiane blokując rekord i se poszedł ....na tydzień na
zwolnienie i co ? transakcja wsi ..rekord zablokowany. Jak by nie dumał ...
pytanie aktualne a po co to ?
pozdrawiam
jasiek
A słyszał Ty o problemie straconej modyfikacji? Najprostszym sposobem
jego rozwiązania jest właśnie nałożenie blokady przed rozpoczęciem
edycji... Oczywiście można stosować strategię optymistyczną ale jak ktoś
lubi pesymistyczną?
--
z pozdrowieniami
Adam Siwoń
>> A na końcu może zrozumiesz, że kolega Tomasz się pomylił, pisząc
>> przykładowy kod SQL, co zauważył Morff, a czego ja nie zauważyłem.
>> Poza tym nikt nie pisał o blokowaniu tabel sensu stricte, tylko o błędnym
>> UPDATE Tomasza, które w efekcie zablokuje wszystkie rekordy w tabeli.
>> I nie CAŁĄ tabelę, bo np. nadal będzie można dopisywać do niej rekordy.
>
> masz rację moja pomyłka ale to nie zmienia wymowy wywodu jezeli blokujemy
> wybrany rekord na czas edycji to czym żesz to jest, jak nie zdublowaniem tej
> samej operacji. W pierwszym kroku blokujemy po przez wykonanie update które
> nic w sumie nie robi samo siebie zmienia i to na kluczu ID /jezeli to jest
> klucz/ a w drugim etapie dokonujemy zmiany na powiedzmy 3 polu tabeli i
> konczymy transakcje / tak sie domyslam/ więc po grzyba wykonywac ta pierwszą
> operacje ? Kiedy otworzenie dla tej drugiej operacji transakcji wykona to
> samo: uniemozliwi innemu userowi zmian w updatowanym rekordzie :(.
Niezupełnie; tu nam tu opisujesz system optymistycznego blokowania, a my
cały czas rozmawiamy o blokowaniu pesymistycznym.
Różnica jest i to istotna; trzeba doczytać...
> Strata czasu, obciazenie łacza, a i mozliwośc przypału ...user wszedł se do
> tabeli rozpoczoł zmiane blokując rekord i se poszedł ....na tydzień na
> zwolnienie i co ? transakcja wsi ..rekord zablokowany. Jak by nie dumał ...
> pytanie aktualne a po co to ?
Właśnie po to, żeby ten rekord zablokować w sposób pesymistyczny; czyli
przed rozpoczęciem zmiany (update, delete) blokuję rekord dla siebie,
aplikacja robi co musi, wysyła odpowiednie polecenie do serwera i
zdejmuje blokadę.
Problem "wiszących" blokad w takim przypadku będzie zawsze i są różne
metody ich rozwiązywania; zazwyczaj jest to timeout, np, w MS SQL jest
wielce pożyteczne polecenie SET LOCK_TIMEOUT; domyślnie wyłączone, czyli
blokada czeka aż do jej zwolnienia.
Przy braku mechanizmu blokowania, każdy może rozpocząć zmianę dowolnej
informacji nie wiedząc o tym, że ktoś już wcześniej rozpoczął jej
edycję, a w bazie danych pojawią się ostatnie zmiany; no i mamy "fajne
jaja"...
--
wloochacz
Takie blokady stosowano przy użyciu ibexpress bo inaczej transakcje w ogóle
nie działały i nazywa się pesymistyczne blokowanie. Przy dbexpress to nie
jest potrzebne. Drugi użytkownik może edytować jednocześnie i dopiero
zatwierdzenie zmian przez jednego z nich blokuje innych użytkowników w taki
sposób że jeśli oni próbują zatwierdzić zmiany to dostają wyjątek z
transakcji. To jest optymistyczne blokowanie, stosowane najczęściej tzn gdy
jest mała szansa na jednoczesny zapis na tym samym rekordzie w dużej bazie
danych.
Natomiast bzdurą jest to, że blokowanie pesymistyczne w DBX nie jest
potrzebne. Pesymistyczne blokowanie jest potrzebne zawsze, gdzie jest
potrzebne.
Jak myślisz, dlaczego jedną z nowości ADO.NET 2.x jest możliwość
blokowania pesymistycznego?
Ponieważ architekt uznał, podobnie jakTy, że taka możliwość jest
"niepotrzebna".
Odsyłam do wątku po szczegóły...
--
wloochacz
> Optymistyczne blokowanie nie spowoduje awarii bazy danych ale w
> bazach, w których następuje często jednoczesny dostęp do tego samego
> rekordu, przedłuży i utrudni wykonywanie operacji. Przy zakleszczeniu
> silnik bazy danych sam powinien rozpoznać ten stan i wycofać jedną z
> czekających transakcji automatycznie.
Nie chodzi o deadlocki, tylko o problem utraconej modyfikacji.
A to jest sytuacja, którą wygodnie i pewnie można obsłużyć za pomocą
pessmisting locking - niezależnie od użytej technologii dostępowej i
serwera bazy danych.
Sam używam permanentnie mechanizmu CachedUpdates i blokowania
optymistycznego. Ale tam gdzie to niezbędne, blokuję pesymistycznie.
--
wloochacz
> Sam używam permanentnie mechanizmu CachedUpdates i blokowania
> optymistycznego. Ale tam gdzie to niezbędne, blokuję pesymistycznie.
A np. gdzie jest to niezbedne?
--
pozdrawiam
Norbert
--
wloochacz