Esercitazione Database - Parte 3


1. Introduzione

Obiettivo di questa esercitazione è introdurre una corretta gestione transazionale nel codice dei Web Services realizzati sinora.

2. Scenario

Viene fornito un progetto per eclipse che implementa una semplice gestione degli ordini di un negozio.

Negozio.tar.gz

  1. Scompattare l'archivio

  2. In eclipse, selezionare File > Import > General > Existing Project Into Workspace

  3. Nella finestra che compare, inserire nel campo Select an archive file.. il jar appena scaricato

  4. Aggiungere al progetto le librerie necessarie (CXF e JRE)

Il progetto contiene già un fuitore del Web Service, nella classe org.negozio.client.OrdiniClient, che invoca le due operazioni esposte, addOrdine, listaOrdini e buyOrdini, e ne stampa il risultato. Per eseguirlo selezionare Run > Run As...> Java Application.

Oltre al client è incluso il Web Service, di cui occorre completare l'implementazione della classe org.negozio.OrdiniImpl, deployabile in tomcat con il comando File > Export > Web > WAR File

Il Web Service richiede un database. Nel caso non fosse stato gia' fatto, creare la tabella per memorizzare gli ordini:

CREATE TABLE ordini(
    codfiscale VARCHAR(255) NOT NULL,
    idordine VARCHAR(255) NOT NULL,
    pagato BOOLEAN DEFAULT FALSE
);

Se si possiede già la tabella creata nelle scorse lezioni, è possibile modificarla per aggiungere la colonna "pagato":

ALTER TABLE ordini 
ADD COLUMN pagato BOOLEAN DEFAULT FALSE;

3. Phantom Row

Una volta installato il Web Service ed eseguito il Client, l'output ottenuto assomiglia a questo:

Richiesta aggiunta ordine [CF:AAABBB0001][idOrdine:43]
Richiesta aggiunta ordine [CF:AAABBB0001][idOrdine:426]
Richiesta aggiunta ordine [CF:AAABBB0001][idOrdine:4988]

Lista Ordini per l'utente [AAABBB0001] 
-----------------------------------
	idOrdine	pagato
	43		    false
	426		    false
	4988		false
Ordini da pagare: 3

Richiesto pagamento ordini....

Richiesta aggiunta ordine [CF:AAABBB0001][idOrdine:1548]
Richiesta aggiunta ordine [CF:AAABBB0001][idOrdine:2064]
Richiesta aggiunta ordine [CF:AAABBB0001][idOrdine:1426]

... pagamento ordini effettuato. Pagati 3 ordini.

Lista Ordini per l'utente [AAABBB0001] 
-----------------------------------
	idOrdine	pagato
	43  		true
	426 		true
	4988		true
	1426		true
	1548		true
	2064		true
Ordini da pagare: 0

Vediamo in dettaglio cosa succede:

  1. L'utente inserisce 3 ordini invocando l'operazione addOrdine

  2. L'utente richiede la lista degli ordini, con il metodo getListaOrdini, dove si vedono i 3 nuovi ordini da pagare.

  3. L'utente invia la richiesta di pagamento di tutti gli ordini con il metodo buyOrdini. Questo metodo simula le interazioni con un istituto bancario con l'introduzione di una sleep di 5 secondi.

  4. L'utente, mentre il pagamento con la banca e' in corso, inserisce ulteriori 3 ordini.

  5. Al termine della transazione di pagamento, l'utente riceve la notifica del pagamento dei primi 3 ordini.

  6. L'utente richiede la lista degli ordini, ma tutti e 6 gli ordini effettuati risultano pagati, non solo i primi 3.

Questo è un tipico problema transazionale chiamato Phantom Row, che provoca la comparsa di nuovi record (Phantom Row) all'interno di una transazione in cui non sono avvenute scritture.

4. Soluzione al problema di Phantom Row

Modificare la logica del Web Service, implementata nella classe org.negozio.OrdiniImpl, per risolvere il problema del Phantom Row e ottenere che al termine dell'esecuzione del client risulti corretto l'aggiornamento degli ordini pagati.

Suggerimento:

5. Altre problematiche derivate dalle transazioni

Per approfondire il tema delle problematiche riscontrabili nella gestione delle transazioni e ricrearne alcune situazioni si rimanda all'articolo Esempi di errori nelle transazioni concorrenti

Footer BGFooter BG
Tito Flagella - © 2007-2015