Lock pessimistico in Ado.Net con Ms Access

di il
4 risposte

Lock pessimistico in Ado.Net con Ms Access

Gentili,
sto tentanto di applicare il lock pessimistico durante l'aggiornamento di una riga in Ms Access.
Premesso che ho trovato tutti esempi per SqlServer e relativo namespace, etc ho provato ad implementare una routine usando i relativi oggetti oledb:

        public void UseTransactions()
        {
            bool accessoVietato = false;
            using (OleDbConnection connDb = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Luciano\Desktop\dbProva.accdb"))
            {                
                connDb.Open();                
                do
                {
                    //OleDbTransaction transaction = connDb.BeginTransaction(System.Data.IsolationLevel.Serializable); // RITORNA ERRORE
                    OleDbTransaction transaction = connDb.BeginTransaction(System.Data.IsolationLevel.RepeatableRead); // RITORNA ERRORE
   
		       // leggo dalla tabella contatori il campo num_ultimo_ordine
                        contatoriCmd = new OleDbCommand(...., connDb, transaction);
                        
                         // aggiorno nella tabella contatori il campo num_ultimo_ordine (qui dovrebbe bloccare l'aggiornamento il lock)
                        updateCmd = new OleDbCommand(...., connDb, transaction);

                        // inserisco nella tabella testate_ordini il nuovo ordine con Id = num_ultimo_ordine;
                        insertCmd = new OleDbCommand(...., connDb, transaction);
                         
                    try
                    {
                        contatoriCmd.ExecuteQuery();                        
                        updateCmd.ExecuteNonQuery();
                        insertCmd.ExecuteNonQuery();
                                               
                        transaction.Commit();
                        accessoVietato = false;
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        Console.WriteLine(ex.Message);
                        System.Threading.Thread.Sleep(1000);
                        accessoVietato = true;
                    }
                } while (accessoVietato);
            }
        }
    }
L'esempio non è del tutto corretto e coerente, ma in pratica nella realtà voglio effettuare una transazione con più comandi sql, se non vanno a buon termine faccio il rollback e ritento ancora, applicando il locking pessimistico. Purtroppo nella riga dove definisco il tipo di IsolationLevel a Serializable o RepeatableRead mi ritorna un errore
Messaggio=Impossibile supportare il livello di isolamento specificato o il suo potenziamento.
Se io imposto IsolationLevel con gli altri valori previsti dall'enum non mi dà errore, ma non so a questo punto se il lock pessimistico viene rispettato oppure no.
A voi è capitata una situazione del genere? E' un limite di Oledb?
Eventualmente potrei gestire con un lock ottimistico usando un DataSet?
Grazie in anticipo a chiunque vorrà rispondermi.
Lucius.

4 Risposte

  • Re: Lock pessimistico in Ado.Net con Ms Access

    Salve Lucius,
    sinceramente non so se il motore di Access supporti l'impostazione del livello di isolamento come tu hai fatto...
    detto cio', non so neanche se Access supporti il lock pessimistico... sono anni che non lo uso piu'

    SQL Server lo supporta, tramite ad esempio Ado.Net... ti riporto pero' la premessa in questo senso di David Sheppa in :
    "Pessimistic locking is a poweful and somewhat dangerous feature. Be afraid. Be very afraid...."
    il concetto e' molto chiaro, in quanto prevede che la riga editata sia sottoposta a lock esclusivo al momento stesso dell'inizio dell'editing, quindi eseguendo una SELECT con un'isolamento REPEATABLE READ in effetti blocchi la riga proiettata rendendola inaccessibile ad altri, risultato comunque ottenibile anche senza impostazione del livello di isolamento ma specificando la clausola
    SELECT ... WITH (UPDLOCK) ...;
    nel comando di proiezione.

    al di la' di tutto questo, un lock ottimistico e' (solitamente) SEMPRE "migliore", in quanto permette una maggiore scalabilita' ed un migliore uso delle risorse server, e tale livello di lock e' quello di default.

    e comunque, inlistando il "blocco" di comandi in una transazione, rende comunque atomica l'operazione, e Ado.Net e' molto bravo a gestire le transazioni, quindi a mio parere dovresti procedere in questo senso...
    salutoni romagnoli
    --
    Andrea
  • Re: Lock pessimistico in Ado.Net con Ms Access

    Salve Andrea,
    grazie mille intanto per la risposta iper precisa.
    In effetti ho provato stamattina ad effettuare delle prove di lock pessimistico con Sql Server impostando l'isolation level a RepeatableRead (dove Access dà problemi) ed in effetti non ritorna errore, a questo punto penso che proprio non sia possibile su Access per la diversa costruzione dei due db.
    Ok per quanto riguarda il lock ottimistico infatti penso che tenterò questa soluzione, l'unico mio dubbio riguarda la select che hai scritto
    SELECT ... WITH (UPDLOCK) ...;
    Se ho ben compreso crea il blocco dell'aggiornamento se eseguita all'interno di una transazione vero?
    E in MS Access sarà utilizzabile oppure anche per questa soluzione esiste lo stesso limite dell'isolationlevel? Devo provare.
    Saluti ed ancora grazie.
    Lucius
  • Re: Lock pessimistico in Ado.Net con Ms Access

    Salve Lucius,

    luciusinfabula ha scritto:


    Ok per quanto riguarda il lock ottimistico infatti penso che tenterò questa soluzione, l'unico mio dubbio riguarda la select che hai scritto
    SELECT ... WITH (UPDLOCK) ...;
    purtroppo NON penso sia disponibile neanche questo HINT (https://docs.microsoft.com/it-it/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver15)...
    Se ho ben compreso crea il blocco dell'aggiornamento se eseguita all'interno di una transazione vero?
    eleva e mantiene un lock, a prescindere dalle transazioni...

    ma "lascia perdere" visto che sono specificita' di SQL Server...

    usa i tuo Command con una transazione esplicita "normale" e dovresti essere comunque a posto

    salutoni romagnoli
    --
    Andrea
  • Re: Lock pessimistico in Ado.Net con Ms Access

    Salve Andrea,
    rispondo con i miei soliti tempi biblici.
    Devo dire che ho implementato il tutto seguendo i tuoi consigli con Dapper come Orm creando una unica transazione che effettua alcune query e se tutto va bene inserisce e modifica i record nelle varie tabelle interessate.
    Essendo il tutto relativo ad una Api da remoto ho impostato un ciclo di max 5 tentativi nello spazio di qualche secondo in cui tenta la transazione prima di ritornare una risposta negativa, ed il tutto mi pare molto funzionale ed efficace.
    Che dire: grazie mille.
    Lucius
Devi accedere o registrarti per scrivere nel forum
4 risposte