# Transazione (basi di dati)

Nell'ambito dei DBMS si definisce transazione una sequenza di operazioni che, quando eseguita correttamente, produce una variazione dello stato della base di dati. Affinché sia considerata corretta una transazione deve godere di alcune proprietà, dette "ACIDe".

## Descrizione

Una transazione, per essere tale, deve godere delle cosiddette proprietà ACID, in particolar modo nei sistemi in cui possono essere eseguite più transazioni contemporaneamente. La transazione è un sistema di tipo on/off che non può concludersi in uno stato intermedio. Le transazioni sono normalmente implementate da Database management system o da gestori di transazioni (application server o ambienti direttamente installati sulla macchina host dove risiede il database (per eswmpio CICS)).
Le transazioni devono possedere le seguenti proprietà logiche: Atomicity, Consistency, Isolation, e Durability (in acronimo ACID).
In caso di successo, il risultato delle operazioni deve essere permanente o persistente, mentre in caso di insuccesso si deve tornare allo stato precedente all'inizio della transazione.

## Gestione

Nei linguaggi di accesso ai DBMS, la gestione delle transazioni fa parte del Data Manipulation Language (linguaggio di manipolazione dei dati). Infatti, le modifiche allo schema del database o alle autorizzazioni non sono facilmente gestibili con transazioni. Si dice che il DBMS è transazionale se è capace di garantire e mantenere l'integrità dei dati, vale a dire se la transazione non può finire in uno stato intermedio (sistema on/off). Le transazioni in linguaggio SQL iniziano con un'istruzione BEGIN TRANSACTION e si concludono con un COMMIT (con eventuale notifica di transazione completata correttamente), oppure con un ROLLBACK, ad esempio in caso di errore (abort) e ripristino dello stato iniziale (in modo automatico o manualmente).

## Esecuzione

Un tipico flusso di esecuzione di una transazione è il seguente:
* Prima di eseguire una transazione, si esegue un'istruzione di "inizio transazione".
* Si eseguono le operazioni di interrogazione e modifica dei dati.
* Se si riscontra qualche anomalia, si esegue un'istruzione detta di abort, per abortire la transazione che produce un meccanismo di rollback.
* Se si sono eseguite tutte le operazioni senza riscontrare anomalie, si esegue un'istruzione detta di commit, per confermare la transazione.
Alcuni sistemi non prevedono un'istruzione di inizio transazione, perché quando ci si collega al DBMS, si inizia automaticamente una transazione, e quando si esegue un commit o un rollback, si inizia automaticamente un'altra transazione.
Se ci si scollega dal DBMS senza eseguire un commit, alcuni DBMS eseguono automaticamente un commit (autocommit), altri un rollback.
Per implementare una transazione, tipicamente si usa un'apposita area d'appoggio del disco fisso in cui vengono copiati i dati originali appena prima di essere modificati. Quando viene eseguito un commit, i dati originali copiati vengono eliminati. Quando viene eseguito un rollback, si ricopiano indietro i dati originali copiati. Pertanto, un commit è più efficiente di un rollback.

### Annullamento

In caso di errori durante l'esecuzione potrebbe essere necessario abortire la transazione, attivando una procedura di annullamento o rollback (in inglese).
Esistono due tipi di abort:
* Abort a run-time, che viene lanciato all'interno dell'esecuzione della transazione quando il DBMS riscontra qualche anomalia, come per esempio una divisione per 0 ed esegue automaticamente un rollback;
* Abort di sistema, che viene lanciato nel caso in cui si verifichi un errore di sistema come l'interruzione brusca del DBMS, per intervento esterno, o per un bug, o per spegnimento improvviso del computer. Il DBMS, quando viene riattivato, esegue automaticamente il rollback delle transazioni che erano in corso al momento del crash.
Una possibile causa del fallimento di una transazione è l'insufficienza di spazio d'appoggio in memoria per copiare i dati originali.

## Implementazione

Nei DBMS le transazioni vengono processate dal transaction processing. Una query (ovvero un'interrogazione alla base di dati) e altre azioni vengono raggruppate in una transazione che deve essere eseguita atomicamente, isolatamente dalle altre e comportando eventualmente una modifica permanente del database. Tale comportamento è assicurato dal
* Concurrency Control Manager o WorkSpace privato che garantisce l'atomicità e isolamento
* Logging / Recovery Manager che garantisce la durabilità e coerenza.

### Concurrency Control Manager o WorkSpace Privato

La transazione effettua le modifiche su una copia della risorsa database. Se essa non termina con successo la copia viene distrutta, altrimenti le modifiche fatte sulla copia vengono rese permanenti attraverso l'operazione di commit. Il sistema ne garantisce in questo modo l'atomicità. Le transazioni devono essere eseguite in isolamento le une dalle altre ma spesso molte transazioni vengono eseguite concorrentemente nello stesso sistema. Il concurrency control manager si assicura che le singole azioni delle varie transazioni vengano eseguite in un ordine tale da non interferire le une con le altre (isolamento). Il Concurrency Control Manager viene realizzato tramite due istruzioni primitive:
* lock, istruzione tramite la quale si afferma che una risorsa è bloccata da una determinata transazione;
* unlock, istruzione tramite la quale si afferma che una risorsa è stata liberata da una determinata transazione.
La serie dei lock viene memorizzata nella lock table (sezione del DBMS apposita). Il concurrency control manager ha anche il compito di risolvere i deadlock causati dai lock facendo abortire una o più transazioni. Per prevenire i lock e gestire al meglio le transazioni si introduce il concetto di scheduler. Lo scheduler ha il compito di garantire l'isolamento, accogliere una transazione e assegnarle un identificatore unico, chiedere al buffer manager del DBMS di leggere/scrivere sul database secondo una particolare sequenza.

### Logging / Recovery Manager

Per assicurare persistenza dei dati del database anche in caso di crash (p.e. stalli nell'accesso delle transazioni alla risorsa), ogni modifica al database viene registrata separatamente sul disco. Il log manager registra queste modifiche per consentire in qualsiasi momento (in seguito ad un crash) al recovery manager di ripristinare il database in uno stato coerente. Il log manager scrive i suoi dati attraverso il Buffer Manager ma prima di continuare si assicura che siano stati effettivamente scritti su disco. Timestamping associa ad ogni transazione e ad ogni risorsa una marca temporale con la quale consentire e controllare l'accesso delle transazioni alle risorse del database.