none
Gestione limitazioni accesso alle tabelle di un database & refresh della form RRS feed

  • Domanda

  • Linguaggio: Vbasic 2010 professionale; Database: Sql Server 2008 R2 Express

    Salve a tutti. Formulo una nuova domanda, ma collegata al thread 'Connessione Sql Server 2008 R2 Express tra 3 pc'. Dato che ora funziona bene il collegamento tra client e server, ho provato a lanciare l'applicazione sui 3 pc, e tutte le modifiche fatte da un utente aggiornano correttamente il db, ma a questo punto sono necessarie 2 cose. Facciamo l'esempio che nel programma vi sia una procedura che gestisce un'agenda. Domanda 1: Un utente fissa un appuntamento e quindi in quel momento gli altri due utenti devono poter solo visualizzare l'agenda, ma non modificarla; Domanda 2: non appena l'utente ha fissato l'appuntamento, devo sbloccare l'accesso agli altri 2 utenti, ma nello stesso tempo devo fare in modo che l'appuntamento appena preso, sia subito visibile anche agli altri 2 utenti, quindi una specie di refresh dei dati.

    Queste implementazioni sono fattibili da codice Vbasic, oppure da qualche altra gestione del database, attraverso qualche opzione ad hoc ?  Grazie mille per l'attenzione

    Mauri

    venerdì 27 aprile 2012 15:56

Risposte

  • salve,

    <IMVHO>

    il "primo" punto non e' facilmente risolvibile, anche perche' per sua natura tecnicamente contrario alla natura stessa dei database multiutente, che prevedono la maggior concorrenzialita' possibile... pensa ad esempio ad una biglietteria... sono disponibili 3 posti residui... tutto il mondo si connette al provider del servizio, e se 1 persona e' uscita a prendere il caffe' lasciando "aperto" l'applicativo, tutto il mondo deve aspettare che la persona rientri per vedere se questi abbia in effetti lasciato qualche cosa disponibile... questo scenario, ovviamente ridicolo e triviale, non viene preso molto in esame dai servizi multiutente... la cosa importante e' che, al momento che utenteX acquista realmente, questi biglietti siano ancora disponibili, e che dopo il suo acquisto la disponibilita' sia modificata, il tutto in maniera consistente e per tutti gli utilizzatori, a prescindere che sia il primo, in mezzo o anche l'ultimo utente "in lista di attesa", in quanto questo e' un aspetto "accessorio"... Microsoft ha abbandonato il lock pessimistico con l'introduzione di Ado.NET, che non prevede il cursore lato server pessimistico invece disponibile in ADO classico... cio' significa che non avrai alcun aiuto ne' dal layer di accesso ai dati ne' dal database engine (malgrado questi ancora supporti il cursore server side pessimistico), che invece si occupa di tutt'altra cosa, sempre in aspetto di concorrenzialita', cioe' che il dato sia consistente e valido...

    dovrebbe quindi variare la tua "logica applicativa", nel senso che "tutti" potenzialmente possono variare uno specifico e singolo dato, ma questa variazione deve essere consistente.. potrai quindi utilizzare la modalita' piu' a te confacente, tipo "first wins" o "last wins", ma sta a te decidere... solitamente personalmente preferisco la prima delle 2, e la implemento in Ado.NET tramite le colonne di tipo ROWVERSION, che ad ogni modifica della riga cambiano automaticamente valore... giocoforza, una variazione che comporti 

    UPDATE dbo.tabella
      SET colonna = nuovo_valore
      WHERE colonna_chiave_Primaria = chiave_primaria_letta_al_momento_della_select
        AND colonna_rowversion = rowversion_letto_al_momento_della_select;
        
    IF (@@ROWCOUNT = 0)
      PRINT 'nessuna riga aggiornata, probabile errore di concorrenza';

    ti protegge da concorrenze non controllate... poi dipende come vuoi gestire "l'errore" che dovrai restituire all'utente... potresti sovrascrivere la form con le nuove informazioni da altri salvate, o viceversa forzare comunque le variazioni locali... basta avere una "logica" e seguirla in modo consistente... questo, nell'aspetto "ottimistico di concorrenzialita'"...

    l'aspetto "pessimistico", come detto, non e' direttamente disponibile ma..... la modalita' piu' semplice, e non soggetta a procedure di manutenzione e cleanup generale, e' l'utilizzo di un lock esclusivo di tipo utente... SQL Server rende disponibile una funzionalita' con la quale si puo' "lockare" una risorsa di tipo testuale facendola sottostare a tutta la sicurezza di lock di SQL Server stesso, ma soprattutto senza le problematiche legate magari a colonne di tipo flag (inUso/Libero) tante volte utilizzate a tal scopo, che pero' richiedono interventi manuali manutentivi nei casi di "disastro", quando le operazioni falliscono, o quando crasha la macchina... quest'ultima funzionalita' e' appunto un application lock, dove "tu" dici, prima di eseguire un UPDATE, di lockare un "nome", una "stringa di testo" (possibilmente che univocamente contraddistingua l'effettiva "riga"), per poi rilasciare il lock ad operazione avvenuta.. nel caso di errori o crash, il lock decada automaticamente, senza richiesta di intervento manuale.. ovviamente, pero', richiede che diligentemente, tutti gli applicativi coinvolti nella gestione della risorsa condivisa (la tabella) utilizzino il medesimo principio di lock manuale, aggiornamento, rilascio...

    </IMVHO>

    per la parte "2", forse il SyncFramework puo' esserti di aiuto, ma personalmente non l'ho mai approfondito piu' di tanto...

    saluti


    http://www.asql.biz - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/


    venerdì 27 aprile 2012 23:19
    Moderatore