Aggiungo che lavorando in java su db2 e specificando la query SELECT FOR UPDATE nel visual code "a mano" con il costrutto SQLQuery non viene preso comunque il lock di tipo esclusivo sul record. Questo comportamento è dovuto all'utilizzo della classe IDCachedRowSet invece che della classe java.sql.Statement per l'esecuzione delle query. Vediamo un esempio java dell'utilizzo di IDCachedRowSet che ho usato per verificare questo comportamento:
- Code: Select all
//Instanzio una connessione al database
Connection conn = ...;
conn.setAutoCommit(false);
IDCachedRowSet crs = new IDCachedRowSet();
crs.setCommand("SELECT NM_PROGRESSIVO FROM OPERGEST.PROGRESSIVI WHERE CD_PROGRESSIVO='PROVA' FOR UPDATE OF NM_PROGRESSIVO");
crs.execute(conn);
crs.next();
int progressivo = crs.getInt(1);
conn.commit();
L'esecuzione di questo codice non crea un lock esclusivo sul recod in questione quindi esecuzioni concorrenti non vengono bloccate.
Eseguendo la stessa query tramite la classe java.sql.Statement il comportamento è quello giusto, cioé si genera un lock esclusivo sul record e le esecuzioni concorrenti sono bloccate. Vediamo il codice in questo caso:
- Code: Select all
Connection conn = ...;
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT NM_PROGRESSIVO FROM OPERGEST.PROGRESSIVI WHERE CD_PROGRESSIVO = 'PROVA' FOR UPDATE OF NM_PROGRESSIVO");
rs.next();
int progressivo = rs.getInt(1);
conn.commit();
La conclusione è che anche specificando la query a mano con il costrutto visual code SQLQuery non si riesce a prendere un lock esclusivo sul record, quindi la SELECT FOR UPDATE non funziona neanche in questa modalità. Facendo diversi tentativi sono giunto alla conclusione che l'unico modo per ottenere il risultato voluto utilizzando IDCachedRowSet è scrivere la query nel seguente modo (sempre riferendomi all'esempio DB2):
SELECT NM_PROGRESSIVO FROM OPERGEST.PROGRESSIVI WHERE CD_PROGRESSIVO = 'PROVA' WITH RR USE AND KEEP EXCLUSIVE LOCKS