Domanda

Per gestire il problema della concorrenza, il blocco è una buona soluzione, qualunque sia il blocco di riga, tabella o database?

In caso contrario, come gestire il problema di concorrenza?

È stato utile?

Soluzione

Se credi a Oracle, no, per niente. Questo perché Oracle ha fatto di tutto per evitarlo.

Il problema è che i lettori possono bloccare gli scrittori e gli scrittori bloccano i lettori, e uno scrittore deve aspettare fino a quando tutti i lettori hanno finito con una riga prima di poter scrivere. Ciò ritarda il processo di scrittura e il suo chiamante. I blocchi esclusivi (per la scrittura) vengono mantenuti fino alla fine della transazione, nel caso in cui sia necessario eseguire il rollback della transazione; ciò impedisce ad altre transazioni di vedere il nuovo valore fino a quando la transazione non viene confermata.

In pratica il blocco va generalmente bene se non c'è troppa contesa, lo stesso che con qualsiasi programmazione concorrente. Se c'è troppa contesa per una riga / pagina / tabella (non molti server di database eseguono il blocco dell'intero DB), le transazioni verranno eseguite a turno anziché simultaneamente.

Oracle utilizza il versioning delle righe, dove invece di bloccare una riga per scriverla, viene invece creata una nuova versione della riga. I lettori che devono ripetere le letture ricordano quale versione della riga hanno letto. Tuttavia, si verificherà un errore se un lettore che sta ricordando le sue letture tenta di aggiornare una riga che è stata aggiornata da un altro autore da quando questa transazione l'ha letto; questo per fermare gli aggiornamenti persi. Per assicurarti di poter aggiornare una riga, devi dire che SELEZIONA è PER AGGIORNAMENTO; in tal caso, richiede un blocco: solo una transazione può contenere una riga PER AGGIORNAMENTO alla volta e una transazione in conflitto deve attendere.

SQL Server 2005 e versioni successive supportano Snapshot Isolation, che è il loro nome per il versioning delle righe. Ancora una volta, dovresti chiedere i blocchi di aggiornamento se devi aggiornare alcuni dati che hai appena letto: in SQL Server, usa WITH (UPDLOCK).

Un ulteriore problema con il blocco è la probabilità di deadlock. Questo è semplicemente il punto in cui due transazioni detengono ognuna un blocco su una risorsa di cui l'altra ha bisogno, o in generale un ciclo di transazioni detiene blocchi che vicendevolmente devono progredire. Il server di database rileverà generalmente questo deadlock e interromperà una delle transazioni, eseguendo il rollback: sarà quindi necessario riprovare l'operazione. Qualsiasi situazione in cui sono presenti più transazioni simultanee che modificano le stesse righe ha il potenziale per deadlock. Il deadlock si verificherà se le righe vengono toccate in un ordine diverso; è molto difficile far rispettare l'ordine che verrà utilizzato dal server di database (in genere si desidera che l'ottimizzatore scelga l'ordine più veloce, che non sarà necessariamente coerente tra le diverse query).

Generalmente suggerirei lo stesso del threading: vai con i blocchi finché non puoi provare che stanno causando un problema di scalabilità, quindi scopri come rendere le sezioni più critiche libere da blocchi.

Altri suggerimenti

Devi prima definire il tuo obiettivo. In caso di richiesta concorrente, vorresti vincere l'ultimo utente o il primo utente. Il blocco del database è sicuramente un brutto modo. Prova a bloccare la tabella / le righe il più tardi possibile e rilascia il blocco al più presto.

Il blocco del database - al contrario del blocco di tabelle o righe - è un cattivo modo di gestire la concorrenza; esclude la concorrenza.

Esistono molte alternative ragionevoli alla necessità di codificare da soli una sorta di blocco DMBS. Tieni presente che un certo tipo di blocco sta sempre accadendo (azioni atomiche, ecc.), Ma la chiave è che non vuoi andarci se non è necessario. Non vuoi cenare con i filosofi se non devi. Le transazioni sono un modo per aggirare il blocco, ma questo è principalmente per i commit. Utilizzando un campo che segna / indica che il record è sporco, il (modello di bit sporco) è un altro modo, assicurati di farlo in un modo di accesso atomico. La lingua ha spesso una soluzione adatta come indicato dai post precedenti, tuttavia la lingua in genere supporta solo applicazioni, processi da elaborare, livellare la concorrenza e talvolta la concorrenza deve essere nel database. Non volevo supporre che tu abbia un ricco livello di applicazione, ma se lo fai ci sono molti livelli di astrazione che gestiscono questo per te. TopLink di Oracle è gratuito ed è il fratello più robusto di Hibernate, entrambi i quali ti aiutano a gestire le sfide di concorrenza del database attraverso l'astrazione, i bit sporchi, la memorizzazione nella cache e il blocco lazy. Non vuoi davvero implementarli da soli, a meno che tu non stia programmando una scuola o un progetto personale. Comprendi il problema, ma rimani sulle spalle dei giganti.

Penso di no, perché è completamente " down " e rende la tua applicazione più complessa. La maggior parte delle lingue ha eccellenti tecniche di gestione della concorrenza e anche in questo caso il modo migliore è scrivere codice in grado di gestire la concorrenza "in modo nativo".

Per maggiori informazioni sulla concorrenza in Java: http://java.sun.com/docs/books/ tutorial / essenziali / concorrenza / index.html

Intendi gestire la concorrenza nella tua applicazione o risolvere un problema di concorrenza che stai riscontrando con il database. Se il primo, non mi sembra un buon approccio. In quest'ultimo caso, questa potrebbe essere la tua unica risposta senza riprogettare i tuoi schemi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top