[ itf @ 14.11.2005. 13:01 ] @
Ajd napisite kako vi rjesavate problem viseklijentskog rada gdje vise klijenata odjednom editira isti zapis. Kako sprijeciti eventualne greske jer kada jedan klijent spremi taj zapis on se promjeni i ostalima se javi greska da taj zapis ne postoji.

Ja radim sa ADO komponentama, pa ako moze i za takav pristup rjesenje... Hvala!
[ X Files @ 14.11.2005. 13:48 ] @
Ovo si već jednom pitao, ali bez odgovora ;)

Generalno gledano, znas i sam koliko je sati... Za takve operacije, kada vise
klijentata pristupa istoj bazi - treba server. BCB6 se isporucuje sa InterBase
serverom, ali koliko sam upucen moze da bez problema da radi i sa SQL serverom.

Dakle potrebno je da TVOJA APLIKACIJA pristupa SERVERSKOM PROGRAMU koji
dalje pristupa BAZI. Dakle:

USER EXE -> SEVER EXE -> MDB

... a ne kao do sada:

USER EXE -> MDB

Inace, i pored toga, sa cestim Open/Close/Refresh/Requery moze se izboriti sa
problematikom izmenjenih slogova i sistemskim greskama, ali sve je to na mišiće.

Sistem ce ti biti validan ali traljav.

Da ne pominjem da takav sistem ima smisla za samo 5-10 klijenata (koliko je
meni jednom receno).


Ako neko zna nesto vise neka javi. Ja sam svojevremeno postavljao pitanja u
tom smeru, ali bez odgovora, ili sa nekim uopstenim odgovorima:

http://tinyurl.com/dach5

http://tinyurl.com/8m6d8
(jedan odgovor)
[ itf @ 15.11.2005. 08:27 ] @
Istina je ovo sto pricas. Win XP "kazu" da je na jednoj bazi (Access) moguce maksimalno imati odjednom 10 klijenata. Mi smo ih na faksu spojili 13, ali vec na 5 klijenata komponente za rad daju lazne podatke!

Postoji jedna mogucnost koja uvijek radi, ali je problematicna ako ima puno zapisa. Naime, dinamicki se alocira dataset, pa se sa bazom radi u memoriji. U principu, vi ste stalno odspojeni od baze, te se na nju spajate jedino kada trebate nesto dodati ili izmjeniti. Nas 25 je lupalo ENTER oko punih 3 minute (slucajni unos podataka u bazu) i nigdje stvar nije pukla i nije bilo problema sa komponentama. Ipak, to zahtjeva brdo memorije jer morate imati u memoriji taj dataset ako se njime zelite setati da bi uopce znali sto u bazi ima.


[Ovu poruku je menjao itf dana 15.11.2005. u 09:34 GMT+1]
[ X Files @ 22.11.2005. 14:06 ] @
Trebalo bi da:

LockType = ltPessimistic

... na nekoj tabeli ili upitu ZAKLJUCA otvoreni slog sve do post-a.
[ itf @ 22.11.2005. 14:30 ] @
Jesi ti siguran u to? Radi li to na vise klijenata odjednom?
[ X Files @ 22.11.2005. 15:26 ] @
Ja sam tako postavljao stvari u nekim programima, mada nisam 100% siguran.

Znam da sa PROCITAO da to tako treba da radi!!!

[ itf @ 22.11.2005. 15:48 ] @
I ja sam procitao da to tako treba biti, ali NIJE. Uostalom, sto ako klijent koji otvori neki zapis (i time ga zakljuca ostalim) zaspe na poslu ili ode na kavu.. Moze se dogoditi. Budem sutra stavio resenje koje ce jednostavno prepisati postojeci zapis bez obzira tko ga editira itd..
[ itf @ 23.11.2005. 13:16 ] @
Evo jednog od rjesenja koje se moze koristiti da se sprijece greske poput:
"Row cannot be updated for updating. Some values may have been changed...."
koje se dogadaju pri viseklijentkom radu sa bazom podataka (ADO komponente).

Da bi ovo radilo potrebno je da vasa tablica ima nekakav podatak tipa autonumber.
U ovom slucaju u bazi postoji tablica sljedeceg sadrzaja:

ID (autonumber, primary key)
Ime (Text)
Prezime (Text)

Code:
void __fastcall TForm1::T1BeforePost(TDataSet *DataSet)
{
    // zapamti sve podatke koji trebaju biti spremljeni
    long id = T1ID->Value;
    AnsiString Ime =  T1Ime->Value;
    AnsiString Prezime =  T1Prezime->Value;

    // odspoji se i ponovo spoji na bazu da dobijes "friske" podatke
    T1->Active = false;
    T1->Active = true;

    // provjeri da li je jedan od klijenata vec izbrisao taj zapis 
    TLocateOptions SearchOptions;
    SearchOptions.Clear();
    if(T1->Locate("ID", id, SearchOptions) == false && id != 0){
        Application->MessageBox("Zapis je u medjuvremenu izbrisan!", "Baza", 0);
        T1->Last();
        Abort(); // obustavi post
    }

    if(id == 0)       // id je uvijek 0 kada se dodaje novi zapis
        T1->Append();
    else              // ukoliko se editira postojeci zapis
        T1->Edit();

    // zamijeni podatke 
    T1Ime->Value = Ime;
    T1Prezime->Value = Prezime;
    // post se izvrsava automatski nakon ovoga
}


E sad... ovo bi sve moglo biti i puno ljepse da postoji neki nacin da se odjednom kompletan aktivni zapis spremi u jednu varijablu, te na isti nacin zamjeniti dva zapisa.Zasto? U ovom slucaju samo su dva podatka: Ime i prezime, no sto ako ih je npr. 20? To je vec puno deklaracija varijabli...

...sukladno gore napisanome, potrebno je, eventualno, dodati i dio koda iz gornje funkcije u funkciju BeforeDelete da se sprijeci greska kada neki klijent pokusava izbrisati vec izbrisani zapis.


[Ovu poruku je menjao itf dana 23.11.2005. u 14:17 GMT+1]
[ X Files @ 23.11.2005. 17:38 ] @
Citat:

Da bi ovo radilo potrebno je da vasa tablica ima nekakav podatak tipa autonumber.


Probaj kad budes nasao vremena:

TBookmark

i

GetBookmark()
GotoBookmark()
FreeBookmark()

... tada bi trebalo da ih pamti poziciju i bez ID-a. Mada ne znam kako ce se
ponasati nakon Close/Open.
[ itf @ 24.11.2005. 12:47 ] @
Znam za to, no sto ako je zapis u bookmak-u vec zbrisan? Isto tako, onda ne mozes niti znati da li se Post radi na vec postojecem zapisu ili na novom.


[Ovu poruku je menjao itf dana 24.11.2005. u 18:04 GMT+1]