Qual è la relazione esatta tra una transazione del database e il blocco?


16

Questa è un'umile domanda posta nello spirito di accrescere la mia conoscenza; sii gentile nella tua risposta.

Come sviluppatore di applicazioni di lunga data, so a un certo livello che cos'è una transazione (le uso sempre). Lasciando da parte i livelli di isolamento delle transazioni per il momento, a un livello elevato una transazione consente di completare un blocco di lavoro completamente o per niente e consente una certa quantità di isolamento da altre attività di modifica del database.

So anche che cos'è (in vari database) un blocco, o almeno come ci si comporta (se blocco in modo esplicito una tabella, nessun altro processo o thread può aggiornare nulla su quella tabella).

Quello che sto più distintamente non chiare sul è: in varie banche dati, quando chiudo in modo esplicito una riga o una tabella, sto utilizzando gli stessi costrutti esatti che vengono utilizzati dai servizi di transazione del database sotto le coperte per far funzionare delle transazioni correttamente?

Cioè, mi viene in mente che, affinché una transazione sia atomica e isolata, deve essere bloccata. Questo blocco avviato dalla transazione, nascosto da tranasction, è lo stesso tipo di blocco a cui vari database mi consentono di accedere attraverso costrutti come comandi SELECT FOR UPDATEespliciti LOCK? O questi due concetti sono completamente diversi?

Ancora una volta, mi scuso per l'ingenuità di questa domanda; Sono felice di essere indirizzato a fonti più fondamentali.

Risposte:


12

quando blocco esplicitamente una riga o una tabella, utilizzo esattamente gli stessi costrutti utilizzati dalle strutture di transazione del database sotto le copertine per far funzionare correttamente la transazione?

Sì. Se ciò non fosse vero, il proprio 'blocco' sarebbe limitato ad altri 'blocchi' simili e non interagire con il blocco proprio del motore. Quindi si bloccherebbe una riga in una tabella in modo che non possa essere bloccata da un'altra applicazione nello stesso modo, ma il blocco verrà ignorato dal motore stesso. Queste semantiche sono raramente desiderate. Il più delle volte un'applicazione che blocca una riga significa "bloccarla contro qualsiasi mezzo di accesso / modifica". Lato nota che i meccanismi di bloccaggio che sono strettamente specifica applicazione fanno esiste, perché sono utili. Ad esempio, SQL Server ha i blocchi dell'applicazione .

mi viene in mente che, affinché una transazione sia atomica e isolata, deve essere bloccata.

Il blocco è un mezzo per raggiungere questo obiettivo. La principale alternativa è il versioning. Oggi la maggior parte dei database supporta entrambi (il che significa anche che se 'blocchi' una riga nell'app ma un'altra transazione usa il controllo delle versioni per leggere la riga, la leggerà perché il tuo blocco non blocca le letture con versione).

Stai girando intorno a un concetto noto nel mondo dell'implementazione del database come "protocollo di blocco a due fasi" . l'articolo di Wikipedia collegato è un buon inizio. Se vuoi leggere una spiegazione più dettagliata su questo argomento, ti consiglio di andare in biblioteca e chiedere un prestito sull'elaborazione delle transazioni: concetti e tecniche . Praticamente ogni database là fuori è, in sostanza, un'implementazione di quel libro.



Aha! Ora stiamo parlando. In effetti, in agguato nella parte posteriore della mia mente c'era MVCC . Grazie per la risposta ben articolata, i grandi riferimenti e per aver dedicato del tempo a scavare davvero nella mia domanda.
Laird Nelson,

3

Qualche informazione prima di rispondere alle tue domande:

Nota: questo è correlato a Microsoft SQL Server - RDBMS ........

  • In termini molto semplici, una transazione è una sequenza di lavoro che deve essere eseguita come una singola unità logica nella sua interezza e deve mantenere le proprietà ACID.
  • Qualsiasi RDBMS deve fornire "Strutture di blocco" che possono essere utilizzate per completare la transazione nella sua interezza, preservando l'isolamento della transazione e la sua durata. Ciò garantisce l'integrità fisica del database.
  • Soprattutto, per impostazione predefinita - le transazioni sono gestite a livello di connessione. Pertanto, quando una transazione viene avviata su una connessione, tutte le istruzioni T-SQL (S / I / U / D) eseguite su quella connessione fanno parte della transazione fino al termine della transazione. ( MARS è gestito in modo diverso)

Ora torniamo alle tue domande:

quando blocco esplicitamente una riga o una tabella, utilizzo esattamente gli stessi costrutti utilizzati dalle strutture di transazione del database sotto le copertine per far funzionare correttamente la transazione?

Sì. Ciò significa che è necessario fare attenzione nel determinare la sequenza di dati che verranno modificati e che lasceranno il database in uno stato coerente. In altre parole, l'operazione DML dovrebbe lasciare il database in uno stato coerente che si limiti alle regole aziendali dell'organizzazione. Tuttavia, RDBMS (qui SQL Server) può imporre l'integrità fisica della transazione.

Da BOL: il blocco e il controllo delle versioni delle righe impediscono agli utenti di leggere i dati senza commit e impediscono a più utenti di tentare di modificare gli stessi dati contemporaneamente. Senza il blocco o il controllo delle versioni delle righe, le query eseguite su tali dati potrebbero produrre risultati imprevisti restituendo dati non ancora impegnati nel database.

Questo blocco avviato dalla transazione, nascosto dalla transazione, è lo stesso tipo di blocco a cui vari database mi consentono di accedere attraverso costrutti come SELECT FOR UPDATE o comandi LOCK espliciti?

Tutto in SQL Server è contenuto in una transazione. È quando accedi ai tuoi dati, l'RDBMS deve prendere i blocchi a seconda del livello di isolamento e delle Operazioni che stai eseguendo sui tuoi dati. Controlla questa risposta per maggiori dettagli.

Alcuni buoni riferimenti:


2

Direi che le transazioni fanno parte dell '"interfaccia" del database in un certo senso che tu come sviluppatore decidi quando iniziare, terminare, cosa fare nell'ambito delle transazioni, ecc. I blocchi, come li vedo, appartengono ai dettagli di implementazione e utilizzato per la sincronizzazione dell'accesso a diversi oggetti. Nella maggior parte dei casi il motore stesso decide cosa e per quanto tempo deve essere bloccato. Esistono molti blocchi a livello di sistema che non possono essere manipolati direttamente (ad esempio, il motore potrebbe bloccare determinate aree di memoria). Anche quando si tratta di blocchi DML, molti di essi si verificano dietro la scena (ad esempio, per garantire l'integrità referenziale Oracle e, per quanto ricordo, SQL Server può mettere un blocco su una riga corrispondente nella tabella principale se viene inserito un nuovo record in tabella dei dettagli) a seguito di dichiarazioni DML emesse nell'ambito della transazione.

Quando si tratta di transazioni, ci si può aspettare un comportamento più o meno coerente da qualsiasi RDMS che afferma di rispettare SQL e supportare le transazioni, ma quando si tratta di blocchi, quasi tutti i fornitori utilizzano strategie e terminologie diverse. Per quanto ne so, la parte comune in tutti gli RMDS è che la concorrenza tra le transazioni è definita dal livello di isolamento mentre la concorrenza tra i blocchi è controllata dai tipi di blocco (condivisi, esclusivi, ecc.).

Per riassumere, i blocchi sono un meccanismo di basso livello per controllare la coerenza di oggetti e concorrenza. I blocchi possono essere emessi durante l'esecuzione delle istruzioni SQL. Dipende dall'implementazione a livello di isolamento delle transazioni, il motore può inserire diversi tipi di blocchi sugli oggetti interessati (righe, gruppi di righe, indici, ecc.). È disponibile un numero limitato di comandi per eseguire manualmente i blocchi ( SELECT FOR UPDATE, LOCK). I blocchi DML possono essere intensificati (dipende da RDMS, ad esempio, nella riga riga-> pagina-> partizione-> di SQL Server). I blocchi possono anche essere emessi dal motore di database durante l'avvio della connessione, i backup, il ripristino, la ricompilazione di procedure / trigger / funzioni / ecc., L'avvio, gli arresti, ecc.

Non sono sicuro che risponda alla tua domanda, ma spero che abbia senso.


Grazie per il tuo commento. Sei decisamente il più vicino finora. Sto ancora cercando di vedere se le transazioni sono sempre implementate in termini di blocchi utilizzati da, diciamo, espliciti LOCKo SELECT FOR UPDATEdichiarazioni, o tramite qualche altro meccanismo.
Laird Nelson,

Per quanto ne so, di per BEGIN TRANSACTIONsé non rilascia serrature. I blocchi appariranno dopo i DML all'interno della transazione.
a1ex07,

Chiarimento: intendevo BEGIN TRANSACTIONse stesso non crea blocchi DML; dovrebbe infatti emettere alcuni blocchi interni perché deve allocare risorse, aggiungere una voce alle tabelle di sistema (se presenti) che
contengono

1

Userò il gergo di SQL Server, ma i concetti dovrebbero essere gli stessi per gli altri fornitori:

Ogni comando che esegui viene eseguito all'interno di una transazione. Tale transazione può essere aperta esplicitamente con BEGIN TRAN, o implicitamente, dal motore di database. Il motivo per cui viene aperta una transazione implicita è che il motore deve ancora mantenere la conformità ACID e la possibilità di un rollback.

Quando si esegue SELEZIONA PER AGGIORNAMENTO, significa solo che mentre la transazione è in atto, manterrà un certo blocco.


Grazie per il tuo commento. Questo lo so. Ma la mia domanda è ancora: quando tale transazione viene aperta, il suo isolamento viene realizzato tenendo i blocchi propri? In tal caso, questi blocchi sono gli stessi tipi di blocchi che posso acquisire esplicitamente? O la transazione raggiunge l'isolamento con altri mezzi?
Laird Nelson,

2
Sì, questo è lo stesso meccanismo. L'isolamento si ottiene utilizzando i blocchi in entrambe le modalità, gli stessi blocchi che è possibile acquisire esplicitamente. La differenza è che se non si apre esplicitamente una transazione, i blocchi verranno rilasciati al termine del comando, mentre in una transazione esplicita i blocchi vengono mantenuti fino al momento del commit (non accurati al 100% a causa dei livelli di isolamento, ma questo è il idea generale).
Matan Yungman,

Grazie per il tuo commento. Il motivo per cui sto ponendo la mia domanda è che ho letto da qualche parte che alcuni database usano MVCC come mezzo per realizzare transazioni ACID, che mi sembra essere un modo senza blocco per farlo. In tali casi, quindi, non sono chiaro quando vorrei mai esplicitamente rilasciare un lucchetto. Ma questa è probabilmente una domanda separata. :-)
Laird Nelson

@LairdNelson è il livello di isolamento dello snapshot per SQL Server. Esistente, ma non il meccanismo predefinito per la concorrenza. È l'impostazione predefinita per Oracle o Postgresql, IIRC.
Marian,

0

Il blocco è necessario e crea il database. Ciò impedisce che i dati vengano danneggiati o invalidati quando più utenti tentano di leggere mentre altri scrivono nel database. L'isolamento transazionale viene di solito implementato bloccando tutto ciò a cui si accede in una transazione. Le cattive applicazioni di progettazione fanno un grande uso del concetto di blocco del database :) !! Quindi, per evitare il blocco, concentrati sull'FK e sul layout dei dati.

Si tratta di ACID: - leggi questo e ti schiarirà le idee! ACID è un insieme di proprietà che si desidera applicare quando si modifica un database.

  • **Atomicita
  • Consistenza
  • Solitudine
  • durabilità **

Una transazione è un insieme di modifiche correlate che viene utilizzato per ottenere alcune delle proprietà ACID. Le transazioni sono strumenti per ottenere le proprietà ACID.

Atomicity significa che puoi garantire che tutte le transazioni avvengano, o nessuna di esse; è possibile eseguire operazioni complesse come un'unica unità, tutto o niente, e un arresto anomalo, un'interruzione di corrente, un errore o qualsiasi altra cosa non consente di trovarsi in uno stato in cui sono avvenute solo alcune delle relative modifiche.

Coerenza significa che garantisci che i tuoi dati saranno coerenti; nessuno dei vincoli che hai sui dati correlati verrà mai violato.

Isolamento significa che una transazione non può leggere i dati da un'altra transazione non ancora completata. Se due transazioni vengono eseguite contemporaneamente, ognuna vedrà il mondo come se stesse eseguendo in sequenza, e se uno deve leggere i dati scritti da un altro, dovrà attendere fino a quando l'altro non sarà terminato.

Durabilità significa che una volta completata una transazione, è garantito che tutte le modifiche sono state registrate su un supporto durevole (come un disco rigido) e che anche la transazione è stata completata.

Quindi, le transazioni sono un meccanismo per garantire queste proprietà; sono un modo per raggruppare le azioni correlate in modo tale che, nel suo insieme, un gruppo di operazioni può essere atomico, produrre risultati coerenti, essere isolato da altre operazioni ed essere registrato in modo duraturo.


Grazie per il tuo commento. Sono almeno sensibilmente consapevole delle proprietà di ACID. Ciò su cui non sono ancora chiaro è: le transazioni implementano ACID usando gli stessi tipi di blocchi che posso usare direttamente tramite LOCKistruzioni esplicite o lo fanno usando qualche altro meccanismo?
Laird Nelson,

I database offrono una serie di livelli di isolamento delle transazioni, che controllano il grado di blocco che si verifica quando si selezionano i dati. Letture serializzabili, ripetibili, lettura impegnata, lettura non impegnata.
Up_One
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.