Obiettivo di questa esercitazione è introdurre una corretta gestione transazionale nel codice dei Web Services realizzati sinora.
Viene fornito un progetto per eclipse che implementa una semplice gestione degli ordini di un negozio.
Scompattare l'archivio
In eclipse, selezionare
File > Import > General > Existing Project Into Workspace
Nella finestra che compare, inserire nel campo
Select an archive file..
il jar appena scaricatoAggiungere 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;
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:
L'utente inserisce 3 ordini invocando l'operazione
addOrdine
L'utente richiede la lista degli ordini, con il metodo
getListaOrdini
, dove si vedono i 3 nuovi ordini da pagare.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 unasleep
di 5 secondi.L'utente, mentre il pagamento con la banca e' in corso, inserisce ulteriori 3 ordini.
Al termine della transazione di pagamento, l'utente riceve la notifica del pagamento dei primi 3 ordini.
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.
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:
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