🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: alt.pl.comp.lang.csharp
12 messages
12 total messages Started by Krzysztof Mon, 29 Mar 2004 15:19
Pytanie o prace z ADO.Net
#706
Author: Krzysztof
Date: Mon, 29 Mar 2004 15:19
35 lines
2609 bytes
Hi all
Widze ze grupa sie rozruszalo co mnie bardzo cieszy
Moje pytanie jest dosyc teoretyczne i prosil bym o odpowiedzi praktykow z
wiekszym stazem :)
Chodzi o prace z warstwa ADO.Net i duzymi bazami danych. Dotychczas
pracowalem poprzez DataSet i wszystkie zmiany wykonywalem na nich. Ale od
momentu jak zaczalem pracowac z tabelami o milionie rekordow taka praca
stala sie porazka. Zreszta moze cos zle robie?

Konkretnie pytanie jest takie, z jakich klas i jakich technik (wlasnie
technik, sekwencji metod ADO.Net) korzystac w celu odczytania wierszyi
przekazania ich do DataRow lub bezposrednio do obiektow zdefiniowanych u
sibie (cos a la kastor/TopLink/Hibernate?) oraz z jakich technik korzystac
przy zapisie obiektu/obiektow do bazy w jedej dosc duzej transakcji...


DataSet mial mi zapewnic mozliwosc pracy z "odlaczonymi" danymi, ale w
momencie jak z serwerem zaczynaja pracowac 5 aplikacji jednoczesnie, z czego
3 sa automatami zauwazylem duzy spadek na synchronizacji danych (Update,
AcceptChanges). Moze wiec przeniesc ta warstwe na zapytania (DataReader dla
selectow o ograniczonej ilosci wierszy) a zapisy bezposrednio na baze danych
(SqlCommand z parametrami zapisu?). Problem polega na tym, ze jedna
transakcja to jest wpis w tabele "master" i 3 tabele polaczone z nia kluczem
i na DS takie transakcje sie udawaly. Jak to zrealizowac obecnie? Tylko ze w
ten sposob znika mi warstwa posrednia w aplikacji i zaczynam "dowalac" w
serwer zapytaniami i transakcjami. Ale przy tak wielkich tabelach DS zaczely
mi zamykac pamiec na stacjach roboczych.

Jako BackEnd jest PostgreSQl lub plik Access w zaleznosci od instalacji

Prosze o opinie, ewentualnie pytania "dopytujace" :)


Pozdrawiam
Krzysztof
Re: Pytanie o prace z ADO.Net
#707
Author: Jacek Wo³oszka
Date: Thu, 01 Apr 2004 13:34
47 lines
3271 bytes
> Hi all
> Widze ze grupa sie rozruszalo co mnie bardzo cieszy
> Moje pytanie jest dosyc teoretyczne i prosil bym o odpowiedzi praktykow z
> wiekszym stazem :)
Szpecem nie jestem ale ze ostatnio tez mnie nurtuja podobne problemy to sie
podziele swoimi przemysleniami

> Chodzi o prace z warstwa ADO.Net i duzymi bazami danych. Dotychczas
> pracowalem poprzez DataSet i wszystkie zmiany wykonywalem na nich. Ale od
> momentu jak zaczalem pracowac z tabelami o milionie rekordow taka praca
> stala sie porazka. Zreszta moze cos zle robie?

DataSet i powiazany z nia DataAdapter przy aktualizacjach wykorzystuja
dynamicznie budowane zapytanie SQL - zreszta chyba do tego sluzy obiekt
SQLCommandBuilder wykorzystywany przy DataAdapter.Update
Weic chyba nie ma szczegolnej roznicy poza elegancja kodu w przypadku
korzystania z obiektu Command i DataAdapter - a to sa chyba jedyne dwa
obiektu pozwalajace na aktualizacje danych
> Konkretnie pytanie jest takie, z jakich klas i jakich technik (wlasnie
> technik, sekwencji metod ADO.Net) korzystac w celu odczytania wierszyi
> przekazania ich do DataRow

Gdzies wyczytalem ze do odczytu danych najszybszy jest DataReader- podobno
DataSet korzysta w DataReader

> DataSet mial mi zapewnic mozliwosc pracy z "odlaczonymi" danymi, ale w
> momencie jak z serwerem zaczynaja pracowac 5 aplikacji jednoczesnie, z
czego
> 3 sa automatami zauwazylem duzy spadek na synchronizacji danych (Update,
> AcceptChanges). Moze wiec przeniesc ta warstwe na zapytania (DataReader
dla
> selectow o ograniczonej ilosci wierszy) a zapisy bezposrednio na baze
danych
> (SqlCommand z parametrami zapisu?). Problem polega na tym, ze jedna
> transakcja to jest wpis w tabele "master" i 3 tabele polaczone z nia
kluczem
> i na DS takie transakcje sie udawaly. Jak to zrealizowac obecnie? Tylko ze
w
> ten sposob znika mi warstwa posrednia w aplikacji i zaczynam "dowalac" w
> serwer zapytaniami i transakcjami. Ale przy tak wielkich tabelach DS
zaczely
> mi zamykac pamiec na stacjach roboczych.

Jako ze DataSet jest reprezentacja tabeli w pamieci to moze nie pobierac
wszystkich rekordow tylko uzyc Fill zwaracajacej np 1000 rekordow? Bo
faktycznie zauwazylem ze juz ptrzy kilku tysiacach rekordow uzywana pamiec
rosnie konkretnie
Re: Pytanie o prace z ADO.Net
#708
Author: Krzysztof
Date: Thu, 01 Apr 2004 20:52
25 lines
2250 bytes
> DataSet i powiazany z nia DataAdapter przy aktualizacjach wykorzystuja
> dynamicznie budowane zapytanie SQL - zreszta chyba do tego sluzy obiekt
> SQLCommandBuilder wykorzystywany przy DataAdapter.Update
> Weic chyba nie ma szczegolnej roznicy poza elegancja kodu w przypadku
> korzystania z obiektu Command i DataAdapter - a to sa chyba jedyne dwa
> obiektu pozwalajace na aktualizacje danych
Elegancja nie, ale jest roznica w prostocie. Co jak co ale Tworzenie
aplikacji poprzez napisanie schemy XSD a potem dla tej schemy wygenerowac
automatem klasy obudowujace to jest bajka.

> Gdzies wyczytalem ze do odczytu danych najszybszy jest DataReader- podobno
> DataSet korzysta w DataReader
Ale jest tylko do wypelniania DataSeta, potem pracujesz juz tylko z lokalna
kopi� danych. A ta "kopia" przy 5 milionach rekord�w nie iesci sie w
pamie�i... W wyoberazni rowniez :)

> Jako ze DataSet jest reprezentacja tabeli w pamieci to moze nie pobierac
> wszystkich rekordow tylko uzyc Fill zwaracajacej np 1000 rekordow? Bo
> faktycznie zauwazylem ze juz ptrzy kilku tysiacach rekordow uzywana pamiec
> rosnie konkretnie
I chyba do tego sprowadza sie moje pytanie: Jak zmusic DataSet, by pobieral
tylko te dane, ktore sa potrzebne, ostatnio uzywane i tak dalej...

Pozdrawiam
Krzysztof
Re: Pytanie o prace z ADO.Net
#709
Author: Macko
Date: Fri, 02 Apr 2004 06:53
22 lines
1894 bytes
>> Jako ze DataSet jest reprezentacja tabeli w pamieci to moze nie pobierac
>> wszystkich rekordow tylko uzyc Fill zwaracajacej np 1000 rekordow? Bo
>> faktycznie zauwazylem ze juz ptrzy kilku tysiacach rekordow uzywana pamiec
>> rosnie konkretnie
>I chyba do tego sprowadza sie moje pytanie: Jak zmusic DataSet, by pobieral
>tylko te dane, ktore sa potrzebne, ostatnio uzywane i tak dalej...

DataSet jest tylko pojemnikiem na dane. Dlatego należy dobrze
sformułować zapytanie pobierające dane. Mądrość jest atrybutem
SQLCommand, nie DataSeta ;)

Możesz na przykład operować na polu timestamp (MSSQL), automatycznie
modyfikowanym w przypadku aktualizacji rekordu (po stronie serwera,
oczywiscie), a następnie pobierać rekordy o ts większym od
największego pobranego ostatnio (tyle jeśli chodzi o pobieranie
ostatnio modyfikowanych i dodawanych).

Zdefiniuj sobie kryterium "dane potrzebne", a potem przygotuj
zapytanie i voila!

Pozdrawiam,
Macko
Re: Pytanie o prace z ADO.Net
#710
Author: Krzysztof
Date: Fri, 02 Apr 2004 07:09
28 lines
2313 bytes
> DataSet jest tylko pojemnikiem na dane. Dlatego nale�y dobrze
> sformu�owa� zapytanie pobieraj�ce dane. M�dro�� jest atrybutem
> SQLCommand, nie DataSeta ;)
>
> Mo�esz na przyk�ad operowa� na polu timestamp (MSSQL), automatycznie
> modyfikowanym w przypadku aktualizacji rekordu (po stronie serwera,
> oczywiscie), a nast�pnie pobiera� rekordy o ts wi�kszym od
> najwi�kszego pobranego ostatnio (tyle je�li chodzi o pobieranie
> ostatnio modyfikowanych i dodawanych).
>
> Zdefiniuj sobie kryterium "dane potrzebne", a potem przygotuj
> zapytanie i voila!

Ok, w sumie masz racje, skoro tabela zawiera nie tylko "aktualne" dane ale
rowniez archiwalne to faktycznie takie rozwiazanie jest pewnym
zabezpieczeniem. Tylko co w przypadku wstawiania nowego rekordu do tej
tablei ktory istnieje w bazie a nie w DataSet (duplikacja jakiegos UNIQ a
nie PK?

I jeszcze cos, a co jezeli do pracy potrzebuje caly zakres danych? Pelne
miliony rekordow? Olac DS i przejsc na procedury osadzone (a przynajmniej
tak juz realizuje, logike duzych zbiorow postanowilem osadzic na serwie) czy
tez bawic sie w DataAdaptery i definiowac SQL'e?

> Pozdrawiam,
> Macko
Ja rowniez pozdrawiam
Krzysztof
Re: Pytanie o prace z ADO.Net
#711
Author: Macko
Date: Fri, 02 Apr 2004 10:58
23 lines
2159 bytes
>Ok, w sumie masz racje, skoro tabela zawiera nie tylko "aktualne" dane ale
>rowniez archiwalne to faktycznie takie rozwiazanie jest pewnym
>zabezpieczeniem. Tylko co w przypadku wstawiania nowego rekordu do tej
>tablei ktory istnieje w bazie a nie w DataSet (duplikacja jakiegos UNIQ a
>nie PK?
Nie bardzo rozumiem problem, moze kilka slow wyjasnienia? Co rozumiesz
przez aktualne i archiwalne dane? W trybie bezpolaczeniowym w zasadzie
wszystkie dane mozna uznac za "archiwalne".

>I jeszcze cos, a co jezeli do pracy potrzebuje caly zakres danych? Pelne
>miliony rekordow? Olac DS i przejsc na procedury osadzone (a przynajmniej
>tak juz realizuje, logike duzych zbiorow postanowilem osadzic na serwie) czy
>tez bawic sie w DataAdaptery i definiowac SQL'e?
Nie bardzo rozumiem, dlaczego potrzebujesz calego zbioru (za mala
wiedza o dziedzinie problemu)? Nie mozesz pobierac po 1000 rekordow,
wyliczac podsumy, dociagac kolejne 1000, doliczac, itd.?

Zakladajac jednak, ze nie mozesz, procedury skladowane (mozna tez
pomyslec o zewnetrznych procedurach skladowanych, jesli bardzo zalezy
Ci na wydajnosci) sa dobrym rozwiazaniem.

Pozdrawiam,
Macko
Re: Pytanie o prace z ADO.Net
#712
Author: Marek Janaszewski USUNTO. z adre...
Date: Fri, 02 Apr 2004 14:51
37 lines
2617 bytes
Jacek Wołoszka wrote:
>> Hi all
>> Widze ze grupa sie rozruszalo co mnie bardzo cieszy
>> Moje pytanie jest dosyc teoretyczne i prosil bym o odpowiedzi
>> praktykow z wiekszym stazem :)
> Szpecem nie jestem ale ze ostatnio tez mnie nurtuja podobne problemy
> to sie podziele swoimi przemysleniami
>
>> Chodzi o prace z warstwa ADO.Net i duzymi bazami danych. Dotychczas
>> pracowalem poprzez DataSet i wszystkie zmiany wykonywalem na nich.
>> Ale od momentu jak zaczalem pracowac z tabelami o milionie rekordow
>> taka praca stala sie porazka. Zreszta moze cos zle robie?
>
> DataSet i powiazany z nia DataAdapter przy aktualizacjach wykorzystuja
> dynamicznie budowane zapytanie SQL - zreszta chyba do tego sluzy
> obiekt SQLCommandBuilder wykorzystywany przy DataAdapter.Update
> Weic chyba nie ma szczegolnej roznicy poza elegancja kodu w przypadku
> korzystania z obiektu Command i DataAdapter - a to sa chyba jedyne dwa
> obiektu pozwalajace na aktualizacje danych
>> Konkretnie pytanie jest takie, z jakich klas i jakich technik
>> (wlasnie technik, sekwencji metod ADO.Net) korzystac w celu
>> odczytania wierszyi przekazania ich do DataRow
[...]

Witam!

Jeśli dobrze zrozumiałem, to zamiast przygotować zapytanie w aplikacji,
tworzysz je dynamicznie w czasie pracy programu. Otóż wyczytałem, że taki
sposób jest o tyle nie ekonomiczny że aplikacji traci czas na przepytywanie
serwera o strukturę tabeli. Było właśnie było to jeden z powodów wyboru
rozwiązania z osobny DataAdapterem. Więc chyba jeśli nie ma innej potrzeby
warto przygotowywać zapytania w czasie projektowania aplikacji.

-- 
Pozdrawiam,
Marek Janaszewski
[ j_m...@gazeta.pl ]
Re: Pytanie o prace z ADO.Net
#713
Author: Maciej Łuszczyński
Date: Fri, 02 Apr 2004 17:29
14 lines
1699 bytes
> Jeśli dobrze zrozumiałem, to zamiast przygotować zapytanie w aplikacji,
> tworzysz je dynamicznie w czasie pracy programu. Otóż wyczytałem, że taki
> sposób jest o tyle nie ekonomiczny że aplikacji traci czas na przepytywanie
> serwera o strukturę tabeli. Było właśnie było to jeden z powodów wyboru
> rozwiązania z osobny DataAdapterem. Więc chyba jeśli nie ma innej potrzeby
> warto przygotowywać zapytania w czasie projektowania aplikacji.
A nie jest tak, ze kazde zapytanie przychodzace do SQL Servera jest
parsowane, a nastepnie tworzony jest plan wykonania zapytania, pod
warunkiem, ze nie jest to odwolanie do funkcji lub procedury? Czyzby
DataAdapter potrafil to obejsc? Chetnie dowiem sie czegos wiecej ww
temacie.

Pozdrawiam,
Macko
Re: Pytanie o prace z ADO.Net
#717
Author: Marek Janaszewski USUNTO. z adre...
Date: Fri, 02 Apr 2004 23:07
59 lines
4326 bytes
Jacek Wołoszka wrote:
[...]
>> Chodzi o prace z warstwa ADO.Net i duzymi bazami danych. Dotychczas
>> pracowalem poprzez DataSet i wszystkie zmiany wykonywalem na nich.
>> Ale od momentu jak zaczalem pracowac z tabelami o milionie rekordow
>> taka praca stala sie porazka. Zreszta moze cos zle robie?
[...]

Witam!

Mój najnowszy pomysł co prawa dotyczy zwykłe ADO bez .NET-u, ale myślę że ma
także odniesie tutaj. To, że nie wolno w takim przypadku sprawdzać
wszystkich rekordów to na pewno jest prawa. Z tego co się orientuje samo ADO
(bez .NET) działa podobnie przy kursorze ustawionym na ClientSide. Jeszcze
muszę sprawdzić w informacje o providerze Accessa, ale na pewno tak się
dzieje w przypadku MS SQL. Odchodzi się o tego, że aplikacja jeździ kursorem
po serwerze. Używane są kursory jednokierunkowe, a najlepiej przesłanie
rekordów przez sieć w trybie "węża strażackiego" aby zmniejszyć ruch tła w
sieci. Kiedy aplikacja tak podchodzi do pracy z serwerem będzie mogła
pracować z wieloma serwerami i sama staje się skalowana. Będzie właśnie
mogła działać w większej skali :-) Podobnie wpływa optymistyczny model
lokowania, pesymistyczny jest do przyjęcia tylko w małej skali.
Tyle podłoża teoretycznego.

Zatem jak sobie poradzi skoro aplikacja musi przyjąć odpowiedź na zadane
pytania i to jak najlepiej nie powodując niepotrzebnego ruchu w sieci. Musi
pobrać co jest w danym momencie potrzebne pod dwoma względami. Zarówno pod
względem ilości wierszy i kolumn. Przy założeniu, że średnio każde pole
zajmuje tyle samo miejsca, obcięcie o połowę ilości wierszy i kolumn obniża
czterokrotnie ilość potrzebnej pamięci i transfer przez sieć.

Zatem po pierwsze przygotowujemy zapytanie do widoku listy czy grida,
zawierające tylko niezbędne kolumny, które użytkownik będzie widział oraz
oczywiście wiesze. W najgorszym wypadku pobierzemy tylko x-rekordów. Być
może było by celów dać możliwości ustawiania tego x-a w opcja i ostrzeganie
użytkownika, że przekroczony został ten limit.
Natomiast w przypadku edycji danych pobieramy z bazy do edycji tylko
edytowany rekord i umieszczamy w osobnej tabeli. W tym przypadku zwykle
pobiera się wszystkie kolumny, choć to raczej nie ma pamięciowo znaczenia.
Problem pojawia się jak wyślemy taki rekord z powrotem. Najprawdopodobniej i
tak najrozsądniej będzie posiada dostęp do wszystkich pól. Zależy od modelu
radzenia sobie z sytuacja, że jak użytkownik edytuje dane coś ulega zmianie.

Tak więc do edycji i poglądu mamy dane w osobnych tabela. Jeśli dopuścimy
taką sytuacje to najprawdopodobniej powstanie problem synchronizacji. Po
zmianie trzeba przeładować dane do poglądu. Ma to o tyle sens, że
przekonujemy się jak dane wyglądają na serwerze po zatwierdzeniu zmian.
Powoduje niestety ciągnięcie wszystkiego od nowa przez sieć. Chyba można
temu zaradzić zatwierdzając rekordy paczkami. Jest i problem w drugą stronę.
Użytkownik wybierając edycje może dostać rekord trochę nowszy niż widział go
w poglądzie rekordów.

Szczerze mówiąc nie testowałem tych pomysłów w jakieś wielkiej skali. Ale
wyda, że mają one ręce i nogi.

-- 
Pozdrawiam,
Marek Janaszewski
[ j_m...@gazeta.pl ]
Re: Pytanie o prace z ADO.Net
#714
Author: Marek Janaszewski USUNTO. z adre...
Date: Sat, 03 Apr 2004 20:53
49 lines
3664 bytes
Maciej Łuszczyński wrote:
>> Jeśli dobrze zrozumiałem, to zamiast przygotować zapytanie w
>> aplikacji, tworzysz je dynamicznie w czasie pracy programu. Otóż
>> wyczytałem, że taki sposób jest o tyle nie ekonomiczny że aplikacji
>> traci czas na przepytywanie serwera o strukturę tabeli. Było właśnie
>> było to jeden z powodów wyboru rozwiązania z osobny DataAdapterem.
>> Więc chyba jeśli nie ma innej potrzeby warto przygotowywać zapytania
>> w czasie projektowania aplikacji.
> A nie jest tak, ze kazde zapytanie przychodzace do SQL Servera jest
> parsowane, a nastepnie tworzony jest plan wykonania zapytania, pod
> warunkiem, ze nie jest to odwolanie do funkcji lub procedury? Czyzby
> DataAdapter potrafil to obejsc? Chetnie dowiem sie czegos wiecej ww
> temacie.
[...]

Witam!

Nie, chodziło mi to co się dzieje po stronie klienta. Np. zapytanie
modyfikacji tabeli może być bezpośrednio wprowadzone w czasie tworzenia
aplikacji do obiektu Command w DataAdapterze albo generowane dynamicznie
przez SQLCommandBuilder. Ta druga metodę ma tą niedogodność, że musi odpytać
bazę danych o strukturę tabeli aby móc takie zapytanie wygenerować.

Jeśli chodzi o stronę serwera podobno można obejść proces prasowania
zapytania.
Po pierwsze serwery mogą posiadać własne API. Może to być metoda
wydajniejsza ale na pewno nie łatwiejsza w używaniu.
Po drugie procedury składowane. Podejrzewam, że ich użycie nie wiąże się z
prasowaniem ich treść za każdym razem. Procedury składowane są preferowane
do załatwiania updateing logic. Ale niestety zarówno AFAIK genertor zapytań
zawarta w IDE jaki i SQLCommandBuilder nie pomogą w ich używaniu.
Jest jeszcze wymierająca metoda Embeded SQL. Czyli SQL wpisany pomiędzy
zwykły kod. Takie coś jest także kompilowane i zamieniane na wywołania
funkcji serwera. Komunikacja z zapytaniami następuje przez specjalne
współdzielone zmienne.
Korzystając SQLCommandBuilder nie dosyć, że powoduje interpretacje kodu to
także generacje tego zapytania. Generowanie zapytania może mięć jedną
przewagę w przypadku updateing logic. Można spróbować nie modyfikować
wszystkich pól. W przypadku optymistycznego module, może to oznacza, że nie
napiszemy zmian dokonanych przez innych. Tak automagicznie działało ADO bez
.NET . Ale na ADO.NET ta metoda jest strasznie kłopotliwa więc zwykle wysyła
się wszystkie pola do modyfikacji. Za to rozwiązuje się te problemy szukają
rekordu, który ma być zmodyfikowany uwzględniając wszystkie pola albo wersje
rekordu.

-- 
Pozdrawiam,
Marek Janaszewski
[ j_m...@gazeta.pl ]
Re: Pytanie o prace z ADO.Net
#715
Author: Maciej Łuszczyński
Date: Sun, 04 Apr 2004 11:47
92 lines
6338 bytes
>> A nie jest tak, ze kazde zapytanie przychodzace do SQL Servera jest
>> parsowane, a nastepnie tworzony jest plan wykonania zapytania, pod
>> warunkiem, ze nie jest to odwolanie do funkcji lub procedury? Czyzby
>> DataAdapter potrafil to obejsc? Chetnie dowiem sie czegos wiecej ww
>> temacie.
> Nie, chodziło mi to co się dzieje po stronie klienta. Np. zapytanie
> modyfikacji tabeli może być bezpośrednio wprowadzone w czasie tworzenia
> aplikacji do obiektu Command w DataAdapterze albo generowane dynamicznie
> przez SQLCommandBuilder. Ta druga metodę ma tą niedogodność, że musi odpytać
> bazę danych o strukturę tabeli aby móc takie zapytanie wygenerować.
Spory spadek wydajności IMO. Poza tym staram się stosować zasadę
ograniczonego zaufania i powtarzalnych wyników: do serwera powinno docierać
zawsze to samo. IMO.

> Jeśli chodzi o stronę serwera podobno można obejść proces prasowania
> zapytania.
Zdecydowanie można, ze względu na wydajność nawet należy :) Ale nie
parsowania, tylko układania planu wykonania zapytania.

> Po pierwsze serwery mogą posiadać własne API. Może to być metoda
> wydajniejsza ale na pewno nie łatwiejsza w używaniu.
To dylemat stary jak świat. Trzeba coś wybrać :)

> Po drugie procedury składowane. Podejrzewam, że ich użycie nie wiąże się z
> prasowaniem ich treść za każdym razem. Procedury składowane są preferowane
> do załatwiania updateing logic. Ale niestety zarówno AFAIK genertor zapytań
> zawarta w IDE jaki i SQLCommandBuilder nie pomogą w ich używaniu.
Zarówno procedury, jak i funkcje składowane to po prostu skompilowane plany
zapytania, przechowywane na serwerze. Wywołanie takiej procedury wymaga co
prawda sparsowania (choćby po to, by odczytać parametry, by była możliwość
przekazania wartości z procedury, itp.), ale nie wiąże się (ze zwykle dużo
kosztowniejszym) układaniem planu zapytania.

Nie używam SLQCommandBuildera, za to dość często procedur i funkcji
składowanych. Nie wiem, czy zależy to od wersji VS, ale w moim przypadku
wystarczy po prostu z eksploratora serwera przeciągnąć odpowiednią
procedurę do formatki, a IDE automatycznie stworzy odpowiedni obiekt wraz z
listą parametrów. Konieczne jest następnie przypisanie wartości wszystkim
parametrom (ja robię to ręcznie), ale zakładam, że można zmusić
SQLDataAdapter (nie używam go do aktualizacji) do odpowiedniego
wykorzystania procedury składowanej i automatycznego podstawienia wartości.

> Jest jeszcze wymierająca metoda Embeded SQL. Czyli SQL wpisany pomiędzy
> zwykły kod. Takie coś jest także kompilowane i zamieniane na wywołania
> funkcji serwera. Komunikacja z zapytaniami następuje przez specjalne
> współdzielone zmienne.
Tego nie znam. 

> Korzystając SQLCommandBuilder nie dosyć, że powoduje interpretacje kodu to
> także generacje tego zapytania. Generowanie zapytania może mięć jedną
> przewagę w przypadku updateing logic. Można spróbować nie modyfikować
> wszystkich pól. W przypadku optymistycznego module, może to oznacza, że nie
> napiszemy zmian dokonanych przez innych. Tak automagicznie działało ADO bez
> .NET . Ale na ADO.NET ta metoda jest strasznie kłopotliwa więc zwykle wysyła
> się wszystkie pola do modyfikacji. Za to rozwiązuje się te problemy szukają
> rekordu, który ma być zmodyfikowany uwzględniając wszystkie pola albo wersje
> rekordu.
Jakoś nie jestem przekonany, czy to taka zaleta - nadpisanie tylko części
pól. Włosy na karku mi się jeżą, jak myślę o takiej spójności.
Nie bardzo mi się podoba pomysł automagicznego wyszukiwania rekordu do
modyfikacji. Jestem za spójnym mechanizmem: PK i w oparciu o wartość tego
klucza wstawiamy bądź modyfikujemy.

Troszkę pozwolę sobie opowiedzieć, dlaczego wolę/wolimy procedury
składowane. Jest to ostatni bastion logiki aplikacji. Oczywiście, można
zrobić to samo na triggerach i ograniczeniach, ale procedury wydają się
łatwiejsze w pielęgnacji, debuggowaniu i kontroli. No i całkiem szybkie
przy zapisach dokumentów składających się z wielu linijek. Procedury
działają oczywiście w ramach transakcji, więc spójność danych jest
zachowywana.

Co do ryzyka napisania zmian wprowadzonych przez innego użytkownika: na
poziomie aplikacji, kiedy użytkownik wywołuje edycję, z serwera pobierana
jest ostatnia wersja rekordu. Dzięki temu minimalizujemy ryzyko dwukrotnego
wprowadzania tych samych zmian. 

Jeśli zachodzi konieczność wyłącznej edycji rekordu, stosujemy albo blokady
na poziomie aplikacji (oczywiście wtedy sprawdzane jest to w momencie
rozpoczęcia edycji, nieco trudniej kontrolować ten mechanizm w procedurach
składowanych (a w zasadzie wymaga to większej uwagi)) albo SELECT z
odpowiednimi parametrami.

Jeśli dobrze pamiętam bieg niniejszego wątku, początkowy problem dotyczył
aktualizacji i zapisu dużej liczby danych. IMO bezwzględnie najszybsze będą
w tym przypadku procedury składowane, najwygodniejsze, jeśli da się je
połączyć z SQLDataAdapterem (a powinno to być możliwe).

Pozdrawiam
-- 
Macko
*** A czym się różni Cray od normalnego peceta?
*** Tym, że Cray wykonuje pętle nieskończone w 10 sekund.
Re: Pytanie o prace z ADO.Net
#716
Author: Marek Janaszewski USUNTO. z adre...
Date: Mon, 05 Apr 2004 20:24
108 lines
6974 bytes
Maciej Łuszczyński wrote:
[...]
>> Jest jeszcze wymierająca metoda Embeded SQL. Czyli SQL wpisany
>> pomiędzy zwykły kod. Takie coś jest także kompilowane i zamieniane
>> na wywołania funkcji serwera. Komunikacja z zapytaniami następuje
>> przez specjalne współdzielone zmienne.
> Tego nie znam.

Witam!

Bo raczej jest nie używane, czasem dokumentacja o tym wspomina. AFAIK raczej
do
zastosowania z C++.

[...]
>> mięć jedną przewagę w przypadku updateing logic. Można spróbować nie
>> modyfikować wszystkich pól. W przypadku optymistycznego module, może
>> to oznacza, że nie napiszemy zmian dokonanych przez innych. Tak
>> automagicznie działało ADO bez .NET . Ale na ADO.NET ta metoda jest
>> strasznie kłopotliwa więc zwykle wysyła się wszystkie pola do
>> modyfikacji. Za to rozwiązuje się te problemy szukają rekordu, który
>> ma być zmodyfikowany uwzględniając wszystkie pola albo wersje
>> rekordu.
> Jakoś nie jestem przekonany, czy to taka zaleta - nadpisanie tylko
> części pól. Włosy na karku mi się jeżą, jak myślę o takiej spójności.
> Nie bardzo mi się podoba pomysł automagicznego wyszukiwania rekordu do
> modyfikacji. Jestem za spójnym mechanizmem: PK i w oparciu o wartość
> tego klucza wstawiamy bądź modyfikujemy.

O ile dobrze zrozumiałem to tak właśnie działa zwykłe ADO samo przygotowując
zapytania aktualizujące:
http://www.microsoft.com/mspress/books/sampchap/5354f.asp

Jeśli dobrze zrozumiałem, jak twierdzi autor to działa tak:
1. Do szukania rekordu w czasie aktualizacji używany jest klucz główny plus
zmienione kolumny
2. Tylko zmienione kolumny są włączane do SET w zapytaniu UPDATE.

Moim zdanie wygląda, że zapobiega ten sposób działa nadpisanie poprzedniej
wartości na podstawie starej wartości pola. Czy to powoduje jak jakieś
szczególne zagrożenie dla spójności to nie wiem. Integralność jest
sprawdzana przez różne więzy na poziome samej bazy. Być może to nie jest
dobry scenariusz dla aplikacji zdalnie przetwarzającej dane, ale dobry
scenariusz dla pracy użytkownika z danymi. Użytkownik powinien przygotować
dane, natomiast przetwarzanie bazy na podstawie tych danych powinno nastąpić
w transakcji na serwera.

Słyszałem od kogoś, że w Oraclu jest możliwość zakładanie blokad na
pojedyncze pola. Dlaczego blokada na rekord daje spójność w bazie, a na pole
nie? Jak modyfikacje w jednym rekordzie są robione na podstawie drugiego
rekordu, oczywiście poza transakcjami. to problemy pojawią się takie same. W
transakcja to nie ma się na czym zastanawiać. O ile się orientuje to jest
sprawa bazy danych jak rozwiąże problem albo zgłosi dead lock
(zakleszczenie). Czyli nie można zakończyć dwóch transakcji bo wynik jeden
wpływa na drugą, a druga jeszcze nie skończona więc niepewna i na odwrót.

[...]
> Co do ryzyka napisania zmian wprowadzonych przez innego użytkownika:
> na poziomie aplikacji, kiedy użytkownik wywołuje edycję, z serwera
> pobierana jest ostatnia wersja rekordu. Dzięki temu minimalizujemy
> ryzyko dwukrotnego wprowadzania tych samych zmian.

Dane są załadowane do formularza na ekranie, użytkownik na podstawie
istniejących danych wprowadza modyfikacje. Jeśli w tym czasie, ktoś inny
wpadnie na ten sam pomysł i nastąpi zatwierdzenie jedno po drugim to
procedury składowane na to zaradzą. Musi być przyjęta jakaś strategia, może
być kto ostatni ten lepszy :-)

> Jeśli zachodzi konieczność wyłącznej edycji rekordu, stosujemy albo
> blokady na poziomie aplikacji (oczywiście wtedy sprawdzane jest to w
> momencie rozpoczęcia edycji, nieco trudniej kontrolować ten mechanizm
> w procedurach składowanych (a w zasadzie wymaga to większej uwagi))
> albo SELECT z odpowiednimi parametrami.

Jest to rozwiązanie mniej skalowane i nie zalecane. Jeśli bym sobie pozwolił
na blokowanie rekordu to wstawił bym na formularzu Timera i dał
użytkownikowi określony czas na dokonanie zmian. Jeśli ktoś pójdzie na obiad
to zablokuje pracę na części danych. Chyba jedna model optymistyczny jest
lepszy i lepiej rozwiązywać problemy niż im zapobiegać.

Poza tym takie rozwiązanie z blokowanie działa wtedy kiedy istnieje
bezpośrednie połączenie z bazą danych, zajmuje zasoby serwera, generuje ruch
na sieci. Nie mam z tak wymagającymi problemami do czynienia ale wydaje mi
się, że model optymistyczny jest jednak lepszy jak proponuje literatura. Na
pewno jest rozwiązanie bardziej skalowane i chyba jedyne do zastosowania w
aplikacjach ASP.

> Jeśli dobrze pamiętam bieg niniejszego wątku, początkowy problem
> dotyczył aktualizacji i zapisu dużej liczby danych. IMO bezwzględnie
> najszybsze będą
> w tym przypadku procedury składowane, najwygodniejsze, jeśli da się je
> połączyć z SQLDataAdapterem (a powinno to być możliwe).
[...]

No właśnie, być może skalowalność rozwiązania ma tu także znaczenia. Ale
autor chyba bardziej miał problemy bardziej od strony kilenta niż serwera.
Procedury składowane można z SQLDataAdapterem, jest rozwiązanie zalcena w
książce, której link podałem wcześniej. Gdzieś wyczytałem, że zwracanie
danych przez procedury składowane ma także swoją specyfikę w czasie odczytuj
danych. MS SQL Server tworzy do tego sepcjany kursor. Przetłumaczyłem jego
nazwę jako "wąż strażacki". Napełnia buffor rekordami i czego na jego
opróżnianie nie prosząć kilenta o rozkazy wysyłania rekordów. Ma to być
rozwiązanie bardziej skalowane bo zmiesza ruch tła w sieci.

-- 
Pozdrawiam,
Marek Janaszewski
[ j_m...@gazeta.pl ]
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads