Newsgroup: it.comp.java
Titolo: aiuto Transazioni java

Mi aiutate a risolvere questo problemino?
ho una tabella Ordine(ID, Data, CFCliente)
Si supponga che non sia possibile definire l'attributo ID di Ordine come un 
contatore con auto-incremento, ma che il valore vada settato esplicitamente 
dal programmatore. Scrivere una classe Java che assicuri che eventuali 
invocazioni concorrenti del metodo AddOrder (string Data, String CFCliente) 
non portino mai a situazioni di incongruenza del db. Suggerimento: E' 
possibile usare rollback per gestire errori e/o gestione della concorrenza 
per assicurarsi che errori non possano succedere.
Grazie mille 

Michele wrote:

Non è molto chiaro a me cosa si vuole fare. Una prima soluzione potrebbe
essere definire un metodo statico e synchronized generateID() che generi
una stringa/id lato java. Il fatto che sia synchronized e static ti
garantisce che nessun altro nel programma può generare due ID
contemporaneamente. Però un altro programma o il DBA potrebbe farlo, quindi
forse quello che si vuole in generateID è di fare una select sulla
tabella/sequenza per sapere l'ultimo ID usato e riservarlo.
Luca


Ho dovuto fare una cosa del genere tempo fa (proprio perchè ID non
aveva l'auto-increment e non era possibile fare modifiche al db):come
suggerito nel post precedente, potresti fare una procedura che preleva
dal resultset l'ultimo identificatore generato.
Il prossimo sarà dunque quest'ultimo incrementato di uno...
Più o meno (codice solo esemplificativo e da prendere con le
pinze :) )
public void addOrder(String data, String cf){
//dichiarazione di statement stmt da qualche parte...
String q="select ID from ordine order by ID asc";
ResultSet rs=stmt.executeQuery(q);
int max=0;
if (rs!=null)
while (rs.next()){
max=rs.getInt(1);
}
String q2="insert into ordine values(max,data,cf)";
stmt.executeUpdate(q2);
}

 String q="select ID from ordine order by ID asc";
Qui userei una "select max(ID) from ordine".
La differenza nel tempo di risposta tra le due query è direttamente 
proporzionale al numero di righe.
Certo che il post originario sembra tanto il "copia-incolla" di un 
esercizio per l'università... :)
Ciao,
Paolo

infatti lo è.
Ma cmq il mio problema non è tanto quello di trovare l'id,
ma gestire la concorrenza.
"Pablo Xon" <pabl...@NIENTESPAMconcavi.net> ha scritto nel messaggio 
news:46e26525$0$17951


 ma gestire la concorrenza.
Dovresti chiarire che strumenti hai a disposizione:
devi fare una classe da zero o usi un application server?
Per gestire le transazioni devi usare i metodi commit e rollback della 
connessione JDBC, per la concorrenza o il synchronized o le funzionalità 
messe a disposizione dal tuo app-server.
In linea generale ti serve un metodo tipo questo:
private synchronized int getNextID()  {
   // calcolo del prossimo ID
   return nextID;
}
da chiamare dentro AddOrder.
Ciao,
Paolo

"Pablo Xon" <pabl...@NIENTESPAMconcavi.net> wrote in message 
news:46e26525$0$17951$4faf...@reader1.news.tin.it...

Anch'io ultimamente ho avuto un problema simile di dover ricavare un id 
univoco, solo che invece di usare una query per ricavare l'ultimo id usato, 
ho utilizzato una funzione matematica che faceva uso di 
System.currentTimeMillis() (ovviamennte non prendevo il valore per intero 
perchè sono molti miliardi) e di un'altra funzione che calcolava un ID base 
ricavato dalla data odierna.
Essendo il database condiviso da più client forse la soluzione non evita che 
qualche client calcoli lo stesso id ma credo sia molto difficile che due o 
più client calcolino lo stesso id nello stesso millisecondo.

 più client calcolino lo stesso id nello stesso millisecondo.
E' una buona soluzione.
Anche SQL Server, se non ricordo male, ha una funzione che restituisce 
un "universal ID" generato a partire dal tempo (millisecondi) e dall'ip.
Ciao,
Paolo

 Paolo
In effetti è stata una soluzione abbastanza "con lepezze", ma il tempo
era poco ed il lavoro da fare tanto...
Ciao :)
Sayhem