Newsgroup: it.comp.lang.vo-clipper
Titolo: [CL] Problema con DBAppend ()

Ho un problema piuttosto strano con un programma che usa la funzione
DBAppend (quella delle RDD, non quella di clipper).
Mi succede che in alcuni casi, chiamando la suddetta funzione, si pianta il
programma, ma piantato bene , da non rispondere piu' a niente.
La cosa strana e' che la cosa si verifica solo sotto windows 95 e solo su
qualche macchina. Non e' un problema di rete, come pensavo inizialmente, lo
fa anche in locale.
Avete vissuto esperienze analoghe ?
Preciso che l'applicativo funziona da anni e benissimo sia sotto dos che
sotto win95, e' ultimamente che si sta manifestando questo problema.
Un grazie e buon lavoro a tutti.
--
Ciao.Alberto.

 wrote:
Non so se lo hai gia' fatto ma proverei a mettere
l'exe in modalita' dos esclusiva, poi riprovi. 
(Cosi' almeno vedi se dipende da win)
Per Win 95 c'e' una patch che se ricordo bene
si chiamava Vredir.exe
Ciao,
Eugenio Belli.
 

 si chiamava Vredir.exe
Provo a cercare su oasis ....
Intanto grazie :)
Ciao.Alberto.

 qualche macchina.
Controlla se c'è qualche differenza importante tra i CONFIG.SYS e gli
AUTOEXEC.BAT.
EMG

 si chiamava Vredir.exe
Ho trovato su oasis la patch in oggetto, che poi ho scaricato come
consigliato da loro direttamente dal sito Microsoft. Purtroppo non ha
risolto il problema.
Ciao.Alberto.

 AUTOEXEC.BAT.
Fatto, addirituttura li ho ricopiati ... niente da fare.
Adesso faccio qualche prova piu' a fondo e poi riporto.
Ciao.Alberto.

Scusa l'ignoranza, ma come si fa ? :)
Click destro sull'icona del programma
proprieta',
programma,
avanzate
programma MS/DOS
Se non risolvi, potresti provare a circoscrivere
il problema, con un piccolo programma di test.
Ciao,
Eugenio Belli. 

Ho isolato il problema, accade questo:
- blocco un file con FLock() perche' devo generare le fatture e quindi mi
servono i progressivi univoci
- aggiungo un record con DBAppend (.F.)
in questo preciso istante mi si piante, e non ci sono storie.
Ma la cosa assurda e' che lo fa solo con 95 e solo su alcune macchine, sia
in locale che in rete.
Se parto in modalita' msdos, non fa questo problema.
Ho provato quanto detto da Eugenio, ma non cambia niente.
Allora ho aggirato in questo modo :
PRINOT->(FLock())
....
operazioni
.....
PRINOT->(DBAppend(.T.))  // aggiungo il record ma gli altri si sbloccano
PRINOT->(FLock())   // blocco di nuovo tutto
.....
altre operazioni
.....
PRINOT->(SBlock())
In questo modo funziona, il problema e' sistemato, ma non mi ritengo
soddisfatto della soluzione.
Ciao.Alberto.

Systems after clients were reporting "lock table full" errors.
ciao

 potrebbe forse esserti utile.
Ti ringrazio, un pochino mi conforta, anche se li si parla di ADS, che usa
ovviamente una sua RDD ben diversa, senza contare il problema della rete.
La cosa che mi sorprende e' che a me lo fa anche il locale. Adesso ho
risolto il problema, ma come per tutte le cose non c'e' soddisfazione a non
aver sviscerato il problema :)
ciao.Alberto.

 soddisfatto della soluzione.
Lo credo bene.
EMG

 FLock() e allora va tutto a donnine.
Infatti, anche se e' un caso non comunissimo, ma e' giusto prevedere TUTTO.
Per adesso tiro avanti cosi', ma continuo a fare prove e cercare la
soluzione.
Ciao>Alberto.

 riguarda windows...
Pienamente daccordo, il punto oscuro e' sempre quello.
Ciao.Alberto.

applicativo.
Era solo per capire se in Dos dava lo stesso problema...
allora e' win (guarda caso ;-))
Non so...
forse e' un problema di caching (bios setup)
forse con W98 va ?
Oppure cancellare la dir windows e reinstallare tutto win95?
Non saprei...
Io su una macchina con W95 ho avuto problemi
con la funzione filecopy (se ben ricordo e'delle Ca-Clipper tools)
l'ho sostituita con Copy File .... 
non andava solo su quella macchina...
Auguri
Eugenio Belli.
 

 chiusura.
E non ti conveniva passare ad essa un valore logico per fare il
DBCommit() o meno invece di utilizzare una variabile pubblica?
EMG

 DBCommit() o meno invece di utilizzare una variabile pubblica?
No, ti spiego meglio: il file di lancio del programma definisce una
variabile di ambiente che stabilisce se deve essere fatto il commit o meno,
questa variabile la setta il cliente direttamente, a seconda del proprio
sistema. Quando il mio applicativo parte, legge l'enviroment e setta la
variabile pubblica. Tutte le procedure sbloccano i record usando quella
funzione, per cui in questo modo controllo tutti i punti con una variabile
sola. Forse non mi ero spiegato chiaramente.
Ciao.Alberto.

 sola. Forse non mi ero spiegato chiaramente.
Continuo a pensare che sarebbe stato meglio leggere la variabile
d'environment dentro alla funzione SBLock(). Le variabili pubbliche
bisognerebbe evitarle.
EMG

> Il mio stack e' a 20.000, l'applicativo e' piuttosto pesante.
!!!!!!!!!
20.000 potrebbe essere troppo, e il blocco potrebbe essere dato dal consumo
totale dello stack, dovuto a ricorsione, richiamo di funzioni etc etc etc
Se lanci il programma con //INFO cosa ti restiruisce come DGRUP?
Il valore potrebbe essere troppo basso.
Dimezza lo stack e riprova, un settaggio a 7168 basta per qualsiasi programma.
Lo stack finisce nel DGRUOP, nel quale finiscono le variabile statiche, la
ricorsione, i buffer
creati per aprire i file etc etc. Se e' troppo alto crei un disastro
--
Matteo Baccan
DEV and Login
Technical Writer
http://www.infomedia.it/artic/Baccan

 return (.T.)
Questa funzione e' sbagliata.
Il COMMIT deve essere fatto SEMPRE prima dell'unlock, se lo fai dopo potresti
far accede a dei dati non
consistenti un altro client.
La sequenza giusta, come dicono anche le NG e'
COMMIT
UNLOCK


 si chiamava Vredir.exe
Quella patch serve se hai una macchina windows 95 A o B e metti i dati su un server Win NT.
La funzione DOS che prende la lunghezza dei file, su server NT, restituisce un dato sbagliato. Questo
crea dei problemi in fase di aggiornamento indici e DBF.
Mi sembra che devi controllare la versione di vredir.vxd, ma non ricordo la versione giusta.
Comunque mettendo la patch questo problema si risolve


 sola. Forse non mi ero spiegato chiaramente.
E' una procedura alquanto strana. La COMMIT serve per garantire una consistenza
dei dati ed evitare, ad esempio, di scrivere N record, vedere il povero task
dos che salta, ritornare nell'applicativo ed accorgersi di aver perso tutte le
modifiche.
L'uso della COMMIT dovrebbe essere un MUST e non un: se ha voglia l'utente.


 L'uso della COMMIT dovrebbe essere un MUST e non un: se ha voglia
l'utente.
Si, il tuo ragionamento non fa una piega, solo che l'applicativo a volte
gira su client server , oppure ci sono occasioni in cui , anche se in un
certo senso rischioso, scelgo di disabilitare il commit, ovviamente solo per
momenti ben precisi.
Ciao.Alberto.

 creati per aprire i file etc etc. Se e' troppo alto crei un disastro
Certo, certo ... ci ho sbattuto parecchio la testa su questo maledetto stack
... anche se non riusciro' mai ad andarci daccordo ... io sono abituato a
dominare lo stack, da vecchio programmatore assembler :)))
Ciao.Alberto.

 Comunque mettendo la patch questo problema si risolve
Le versioni giuste sono queste :
vredir.vxd    4.00.1116
vnetsup.vxd   4.00.1112
Ciao.Alberto.

 Questa funzione e' sbagliata.
Hai ragione matteo, per non voler fare il copia incolla, ho cappellato
l'ordine delle cose, che come fai notare tu e' invertito.
Ciao.Alberto.

 Oppure cancellare la dir windows e reinstallare tutto win95?
Oppure cancellarlo e rimetterci DOS :)))))))
Ciao.Alberto.

 bisognerebbe evitarle.
A parte l'appesantimento che avrebbe causato, visto che la funzione viene
usata parecchio, ma forse con i processori moderni non se ne sentirebbe
neanche la differenza, ma:
- quando la variabile viene letta, vengono ovviamente effettuati anche i
controlli del caso.
- la variabile viene scritta in un formato "umano"
- dici che bisognerebbe evitare le variabili pubbliche: sono daccordo che
non occorre abusarne, ma perche' evitarle ? (confesso la mia ignoranza,
magari c'e' scritto da qualche parte) . Ed ingenuamente chiedo allora a cosa
si usano ?
Grazie e buon lavoro.
Ciao.Alberto.

 creati per aprire i file etc etc. Se e' troppo alto crei un disastro
Si, anche se bisogna dire che l'ultima versione del Blinker (la 5.1)
permette di ottimizzare l'uso del DGROUP spostando le variabili statiche
altrove e altri miglioramenti che ora non ricordo. Ma non so come si
faccia ad attivare queste funzioni.
EMG

 UNLOCK
Si, anche se da qualche parte avevo letto anche dei pareri contrari.
Inoltre pare sia meglio far seguire al COMMIT un DBSKIP( 0 ). I
conclusione, io uso questa sequenza:
COMMIT
DBSKIP( 0 )
UNLOCK
EMG

 L'uso della COMMIT dovrebbe essere un MUST e non un: se ha voglia l'utente.
Giusto anche questo! Mi domando come abbia fatto a non rendermene conto
subito...
EMG

 momenti ben precisi.
E la ragione quale sarebbe? Forse per modifiche a più record all'interno
di un loop, giusto? In quel caso un'unica COMMIT alla fine va benissimo.
EMG

 si usano ?
Io parlavo delle variabili pubbliche in generale non in particolare
quelle del Clipper, che comunque sono un retaggio delle versioni pre-5
mantenute più che altro per compatibilità. Perché evitarle? E' scritto
su tutti i libri di informatica. Le variabili pubbliche vanno contro la
tecnica fondamentale dell'information hiding e, accoppiando moduli che
dovrebbero essere indipendenti, ne impediscono di fatto il debugging
affidabile.
EMG
PS. Scusate se continuo a tenere "lezioni" di teoria ma purtroppo vedo
che ce n'è bisogno. :-)

 faccia ad attivare queste funzioni.
Lo spostamento delle statiche fuori dal DGROUP e' automatico, basta linkare in
5.1
Alla peggio puoi evitare la cosa con uno switch che ora non ricordo


 dominare lo stack, da vecchio programmatore assembler :)))
Allora se ti puo' interessare, ci sono due variabili che puoi dichiarare come
external in un programma C linkato in applicativi clipper. Tali variabili sono
extern unsigned int _evalhigh;                      /* EVAL HIGH */
extern unsigned int _estatlow;                      /* EVAL LOW  */
Se crei la seguente funzione
CLIPPER dfDSAvail(){
    _retnl( _estatlow-_evalhigh );
}
hai come ritorno l'ammontare di DGROUP disponibile al momento del richiamo.
Noterai che tale valore cambia a seconda del livello di profondita' delle
funzioni, dei file aperti, dello stack consumato, delle librerie linkate (se
compili con gli switch sbagliati il C mette i suoi buffer nel DGROUP  e non li
pone nell'heap) etc etc
A = hai un bel eval stack fault, se e' clipper a provocarlo, se e' una routine C
.. hai il finimondo.


 si usano ?
L'uso delle pubbliche tende normalemnte a rendere meno leggibile un sorgente.
In realta' sono variabili risolte a runtime, quindi piu' lente di LOCAL o
STATIC, ma questa perdita di performance e' trascurabile


 momenti ben precisi.
Se scrivi un gruppo di record e poi fai una sola commit finale .. be .. in
questo caso
puo' aver senso. Chiaramente tutto solo lock


 UNLOCK
Eccesso di zelo, lo skip 0 serviva per colmare eventuali bug di procedure che non
facevano il flush dei dati.
Comunque anche questa sequenza potrebbe essere corretta, anche se, personalemente,
mettere lo skip prima del commit, e per ottimizzare metterei DBCOMMIT(), il COMMIT
chiama infatti il DBCOMMITALL() provare il .ppo per verificare


 L'uso delle pubbliche tende normalemnte a rendere meno leggibile un sorgente.
Non è solo questione di leggibilità ma soprattuto di accoppiamento
indesiderato tra moduli/classi/funzioni del programma.
EMG

 .. hai il finimondo.
Interessante. Dove si trovano tutte queste informazioni?
EMG

 chiama infatti il DBCOMMITALL() provare il .ppo per verificare
Si, è certamente come dici tu ma dimmi una cosa: se non ci sono dati da
flushare una DBCOMMITALL() non ha la stessa efficienza della DBCOMMIT()?
E se è così, non vale la pena di fare il flush di tutto in modo da
essere sicuri che la situazione sia coerente per gli altri utenti anche
riguardo gli altri DBF?
EMG

 riguardo gli altri DBF?
La commit, mi rocordo, ma qui non ho la certezza, faccia un flush dell'area locale e non
di tutte le aree aperte, ma qui non sono per nulla sicuro. Mi rocordo che avevo fatto
dei test e la commi era piu' performante .. ma anni fa



Corretto, approvo e sottoscrivo


> Interessante. Dove si trovano tutte queste informazioni?
Un po' di decompilazione, un po' di header di fivewin .. etc etc


 puo' aver senso. Chiaramente tutto solo lock
Infatti e' proprio il mio caso, per queste operazioni faccio una raffica di
operazioni sempre sullo stesso gruppetto di record bloccati, poi committo e
sblocco (italianizzazione :))
Ciao.Alberto.

 extern unsigned int _estatlow;                      /* EVAL LOW  */
ecc ecc
Queste sono informazioni preziose, grazie 1000, ne faro' buon uso.
Ciao.Alberto.

 dei test e la commi era piu' performante .. ma anni fa
Ho fatto un test e ho riscontrato una differenza di velocità del 10% in
favore della DBCOMMIT() contro la DBCOMMITALL(). Ritengo comunque sia un
prezzo da pagare più che accettabile per la maggiore sicurezza che offre
quest'ultima. Io però (me ne sono accorto solo ora) uso la prima.
Infatti il mio comando COMMIT è così definito:
#command COMMIT => DbCommit() ; DbSkip( 0 )
Dici che faccio bene o dovrei sostituirla con DbCommitAll()?
EMG