Connessione a un database MS Access (OleDB) con più utenti

2

Sto scrivendo applicazioni C # che memorizzano i loro dati nei database di MS Access, (preferisco usare un diverso tipo di database ma al momento non ho altre opzioni). Le applicazioni sono utilizzate da più persone contemporaneamente e quindi quando ci sono più tentativi di connessione (o qualcuno apre erroneamente una tabella), alcuni di loro non riescono a connettersi.

Per ovviare a questo ho scritto un paio di metodi che ritentono una connessione / disconnessione usando Thread.Sleep (n) all'interno di un ciclo while (mi rendo conto che i tentativi di disconnessione probabilmente non sono necessari ma l'abbiamo lasciato in per ogni evenienza).

C'è un modo migliore per realizzare questo? Stavo leggendo questo thread su " Perché il thread è così dannoso per il sonno " e io pensavo forse nel caso sarebbe andato tutto bene. Preferirei che l'applicazione sembrasse bloccata per qualche secondo piuttosto che apparire un messaggio di errore per l'utente finale, il che causerebbe confusione e la mia posta in arrivo sarebbe inondata dagli utenti che richiedono il supporto. Sto solo guardando questo completamente sbagliato?

x-postato dalla revisione del codice SE , @ mdfst13 consigliato "È possibile ottenere una risposta migliore alla tua domanda principale da Programming.SE, in quanto un modo per risolvere questo problema è aggiungere un servizio intermedio per parlare con il database."

    
posta Rob 31.08.2016 - 02:26
fonte

2 risposte

1

La soluzione che stavo suggerendo è l'introduzione di un servizio che dialoga con il tuo database. La tua applicazione dovrebbe quindi parlare al servizio. Il servizio manterrebbe una connessione permanente (o connessioni se ha più thread o istanze).

Il vantaggio di questo è che invece di riprovare la connessione, il servizio può accodare le richieste. Può elaborare solo un numero fisso alla volta, ma può elaborarli continuamente. Questo dà un throughput più elevato di un sistema in cui si sta aspettando una connessione disponibile. Per prima cosa, elimina la necessità di connettersi o disconnettersi. Ancora più importante, non starà dormendo in attesa che la connessione diventi disponibile.

Un altro vantaggio è che è possibile elaborare la coda di richieste in ordine. Nella tua applicazione, la sfortuna potrebbe portare a un'applicazione che esaurisce i suoi tentativi. Se un'altra applicazione afferra la connessione disponibile appena prima che l'applicazione si riattivi, può eseguire i suoi tentativi anche se era disponibile una connessione. Il servizio risponde sempre alle richieste ed è possibile elaborare prima quello più vecchio. Ciò fornisce un comportamento più prevedibile.

Il primo svantaggio del servizio è che per un singolo cliente, è più sovraccarico. Deve fare tutto lo stesso lavoro di interrogare il database mentre comunica anche con l'applicazione client.

Il secondo lato negativo è che devi eseguirlo da qualche parte. Poiché esiste una contesa per il database, è apparentemente una risorsa condivisa. Forse potrebbe correre lì. O forse no.

Un terzo svantaggio è che è più un lavoro di programmazione. Devi scrivere il servizio intermedio. La maggior parte delle query può essere basata su ciò che l'applicazione ha attualmente, ma poi devi scrivere un servizio che elabora le richieste e modifica l'applicazione per chiamare il servizio piuttosto che il database.

Mentre l'elenco degli aspetti negativi è più lungo, penso che i lati positivi siano spesso più forti. Una maggiore velocità effettiva e un comportamento più prevedibile sono entrambi utili. Gli svantaggi sono tutti indirizzabili. A quanto pare hai un programmatore per fare il lavoro (tu). Spero che tu possa trovare un posto dove eseguire il servizio. E l'aumento del sovraccarico sul caso facile è probabilmente più che compensato dal comportamento migliorato nei casi più difficili. La maggior parte delle persone non noterà un ulteriore secondo di overhead fintanto che ritorna in meno di otto secondi totali. Ma attendere attraverso più tentativi di connessione può portarti oltre la soglia degli otto secondi in cui le persone iniziano a sentirsi frustrate.

Un vantaggio laterale è che questo disaccoppia l'applicazione dal database. Quindi, se si modifica il database, non è sempre necessario ridistribuire l'applicazione. È necessario aggiornare l'applicazione client solo se l'interfaccia del servizio cambia.

Sto pensando a un servizio composto da un'applicazione web. Quindi l'applicazione client passerebbe i parametri che il servizio convertirà in una query di Access. Il servizio impacchetterà i risultati e li rimanderà all'applicazione. Durante l'attesa della richiesta successiva dall'applicazione, il servizio potrebbe elaborare altre richieste. I servizi basati su WSDL sono progettati per questo tipo di cose.

Si noti che ho un'esperienza limitata con C # e Microsoft Access, quindi potrei mancare sottigliezze relative a questi due aspetti. Ho più familiarità con l'utilizzo di questo modello con un frontend Perl o PHP che parla con un servizio C ++ o Java.

    
risposta data 31.08.2016 - 09:32
fonte
0

Quello che stai facendo è chiamato Retry Pattern .

Stai trattando l'errore di connessione come errore temporaneo. Anche se questo non è ottimale, è tutto quello che hai quando lasci le poche connessioni simultanee che hai in palio. Escludendo qualsiasi sistema di accodamento o di messaggistica per gestire l'accesso a questa risorsa limitata, considera l'aggiornamento del tuo sonno ai nuovi giocattoli con fodero di C #:

async e attendi può essere utilizzato per rendere il tuo sonno asincrono. Puoi anche gestire il ritardo in modo dinamico come mostrato in questo esempio del modello di ripetizione .

Vale la pena notare che non è tanto che il sonno è il male, quanto l'uso del sonno nel thread principale della tua app che è malvagio. Ben fastidioso almeno. A volte è bello vedere una finestra ridipingere mentre aspetti.

Un esempio migliore della sostituzione tra sleep, thread, asincrona e attesa rispetto a quanto sono in vena di dare può essere trovato qui

    
risposta data 31.08.2016 - 03:35
fonte

Leggi altre domande sui tag