CodeGym /Corsi /All lectures for IT purposes /Transazioni quando si lavora con un database

Transazioni quando si lavora con un database

All lectures for IT purposes
Livello 1, Lezione 198
Disponibile

Perché sono necessarie le transazioni

Molto spesso, quando si lavora con un database, si verifica una situazione in cui è necessario eseguire molte azioni diverse, ma hanno senso solo insieme.

Ad esempio, stiamo scrivendo un software bancario che dovrebbe fare tre cose:

  • Prelevare denaro dal conto del cliente
  • Aggiungi denaro al conto del destinatario
  • Registrare i dati di registrazione nel "registro di registrazione"

Se si verifica un errore durante l'esecuzione di una di queste azioni, anche le altre due devono essere annullate. È impossibile cancellare denaro dal cliente e non aggiungerlo al destinatario? Bene, o aggiungere al destinatario, ma non cancellare dal cliente?

Quindi, un tale raggruppamento logico di diverse azioni in una sola è chiamato transazione . In altre parole, una transazione è un insieme di azioni che devono essere eseguite solo tutte insieme . Se un'azione non è riuscita o è stata eseguita con un errore, tutte le altre azioni devono essere annullate.

Una transazione di solito ha tre stati:

  • stato iniziale - lo stato del sistema prima dell'esecuzione di un gruppo di azioni
  • stato di successo - stato dopo il completamento del gruppo di azioni
  • stato fallito: qualcosa è andato storto

In questo caso, di solito ci sono tre comandi:

  • inizio/inizio - eseguito prima dell'inizio del gruppo logico di azioni
  • commit - eseguito dopo il gruppo di azioni della transazione
  • rollback : avvia il processo di ritorno del sistema dallo stato di errore allo stato iniziale

Funziona così.

Per prima cosa devi aprire una transazione: chiama il metodo begin() o start() . Chiamare questo metodo indica lo stato del sistema a cui cercheremo di tornare se qualcosa va storto.

Quindi vengono eseguite tutte le azioni, che vengono combinate in un gruppo logico: una transazione.

Quindi viene chiamato il metodo commit() . La sua chiamata segna la fine di un gruppo logico di azioni e di solito avvia anche il processo di messa in pratica di queste azioni.

Ricorda come abbiamo scritto qualcosa in FileWriter: prima tutto ciò che abbiamo scritto viene archiviato in memoria, quindi quando viene chiamato il metodo flush () , tutti i dati dal buffer in memoria vengono scritti su disco. Questo flush() è il commit della transazione.

Bene, se si è verificato un errore durante l'operazione della transazione, è necessario avviare il processo di ritorno allo stato iniziale. Questo processo è chiamato rollback() e il metodo con lo stesso nome ne è solitamente responsabile.

In parole povere, ci sono 2 modi per completare una transazione:

  • COMMIT - confermiamo tutte le modifiche apportate
  • ROLLBACK - ripristina tutte le modifiche apportate

Transazioni in JDBC

Quasi tutti i DBMS possono lavorare con le transazioni. Quindi JDBC ha anche il supporto per questo caso. Tutto è implementato in modo molto semplice.

Innanzitutto, ogni chiamata al metodo execute() dell'oggetto Statement viene eseguita in una transazione separata. Per fare ciò, Connection ha un parametro AutoCommit . Se è impostato su true , allora commit() verrà chiamato dopo ogni chiamata al metodo execute() .

In secondo luogo, se vuoi eseguire più comandi in una transazione, puoi farlo in questo modo:

  • disabilitare AutoCommit
  • chiamando i nostri team
  • chiama esplicitamente il metodo commit()

Sembra molto semplice:

connection.setAutoCommit(false);

Statement statement = connection.createStatement();
int rowsCount1 = statement.executeUpdate("UPDATE employee SET salary = salary+1000");
int rowsCount2 = statement.executeUpdate("UPDATE employee SET salary = salary+1000");
int rowsCount3 = statement.executeUpdate("UPDATE employee SET salary = salary+1000");

connection.commit();

Se si verifica un errore sul server mentre il metodo commit() è in esecuzione , il server SQL annullerà tutte e tre le azioni.

Ma ci sono situazioni in cui l'errore si verifica ancora sul lato client e non siamo mai arrivati ​​alla chiamata al metodo commit() :

connection.setAutoCommit(false);

Statement statement = connection.createStatement();
int rowsCount1 = statement.executeUpdate("UPDATE employee SET salary = salary+1000");
int rowsCount2 = statement.executeUpdate("UPDATE employee SET salary = salary+1000");
int rowsCount3 = statement.executeUpdate("UPDATE multiple typos will result in an exception");

connection.commit();

Se si verifica un errore durante l'esecuzione di un executeUpdate() , il metodo commit() non verrà chiamato. Per eseguire il rollback di tutte le azioni eseguite, è necessario chiamare il metodo rollback() . Di solito ha questo aspetto:

try{
  	connection.setAutoCommit(false);

  	Statement statement = connection.createStatement();
  	int rowsCount1 = statement.executeUpdate("UPDATE employee SET salary = salary+1000");
  	int rowsCount2 = statement.executeUpdate("UPDATE employee SET salary = salary+1000");
  	int rowsCount3 = statement.executeUpdate("UPDATE multiple typos will result in an exception");

	  connection.commit();
 }
 catch (Exception e) {
   connection.rollback();
}

Punti di salvataggio

Con l'avvento di JDBC 3.0, è diventato possibile lavorare in modo più efficiente con il rollback delle transazioni. Ora puoi impostare punti di salvataggio - punti di salvataggio e quando chiami l' operazione rollback () , torna a un punto di salvataggio specifico.

Per salvare è necessario creare un punto di salvataggio, questo viene fatto con il comando:

Savepoint save = connection.setSavepoint();

Il ripristino di un punto di salvataggio viene eseguito con il comando:

connection.rollback(save);

Proviamo ad aggiungere un punto di salvataggio prima del nostro comando problematico:

try{
  	connection.setAutoCommit(false);

  	Statement statement = connection.createStatement();
  	int rowsCount1 = statement.executeUpdate("UPDATE employee SET salary = salary+1000");
  	int rowsCount2 = statement.executeUpdate("UPDATE employee SET salary = salary+1000");

  	Savepoint save = connection.setSavepoint();
 	 try{
      	int rowsCount3 = statement.executeUpdate("UPDATE multiple typos will result in an exception");
 	 }
 	 catch (Exception e) {
    	   connection.rollback(save);
 	 }

	  connection.commit();
 }
 catch (Exception e) {
   connection.rollback();
}

Abbiamo organizzato le transazioni nidificate aggiungendo un punto di salvataggio prima di chiamare il metodo problematico e tornando allo stato salvato chiamando il metodo rollback(save) .

Sì, è molto simile al salvataggio/caricamento nei giochi.

Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION