# Lostupdate & Sperren in JDBC



## Gayson (4. Feb 2007)

Hallo!
Ich soll als Aufgabe von der Uni in einem kleinen Programm das Lostupdate-Problem aufzeigen, dass in Abhängigkeit eines übergebenen Parameters auftreten soll oder nicht. Lostupdate funktioniert wie ich es unten aufgeschrieben habe, das Problem ist noch commit. Er kann im TRANSACTION_SERIALIZABLE-Level keines der executeUpdate, commit oder rollback durchführen, was wohl daran liegen dürfte, dass das DBMS (DB2) im Hintergrund irgendwelche Sperren setzt. Ich weiß irgendwie nicht, wie ich an dieses Problem rangehen soll, damit das Programm zum Ende läuft, habt ihr Ideen?
Danke!!


```
// 1. zwei Connections auf dieselbe Datenbank öffnen
Connection con1 = DriverManager.getConnection(...);
con1.setAutoCommit(false);
Connection con2 = DriverManager.getConnection(...);
con2.setAutoCommit(false);
// 2. Transactionlevel setzen, in Abhängigkeit vom übergegenen Parameter
if (modus.equals("lostupdate")){
   con1.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
   con2.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
} else{
   con1.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
   con2.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
}
// 3. jeweils in einem eigenen Thread werden 2 Updates durchgeführt (habs ein wenig vereinfacht)
con1.executeUpdate("UPDATE konten SET kontostand = 5 WHERE kontonr = 1");
con2.executeUpdate("UPDATE konten SET kontostand = 7 WHERE kontonr = 1");
// 4. Warten, bis die Updates ausgeführt dinf
Thread.sleep(1500);
// 5. Commit
con1.commit();
con2.commit();
```


----------



## SlaterB (4. Feb 2007)

was willst du damit sagen?, dass TRANSACTION_SERIALIZABLE generell nicht geht?

warum dann überhaupt die Uniaufgabe erwähnen, warum so ein komplizierter Code?

```
Connection con1 = DriverManager.getConnection(...);
con1.setAutoCommit(false);
con1.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
// Update
con1.executeUpdate("UPDATE konten SET kontostand = 5 WHERE kontonr = 1");
// 4. Warten, bis das Update ausgeführt sind
Thread.sleep(1500);
// 5. Commit
con1.commit();
```
müsste dann doch genau den gleichen Fehler produzieren
oder klappt das etwa?

ich kann ansonsten nicht weiterhelfen


----------



## Gayson (4. Feb 2007)

Also der Code, den du oben beschrieben hast, funktioniert in TRANSACTION_SERIALIZABLE (grad nochmal ausprobiert, läuft bis zum Ende das Programm). Das Problem muss in 2 Connections, die auf dasselbe Tupel updaten, liegen, sodass das DBMS eine Sperre setzt, und da dann ein Deadlock eintritt... Und da habe ich keine Idee, wie ich das schaffe, das Programm dazu zu bekommen, bis zum Ende zu laufen...


----------



## Gayson (4. Feb 2007)

Was ich halt überhaupt nicht verstehe, ist, warum noch nicht mal das 1. Update klappt . Vom Prinzip her müsste doch 1. Update ausgeführt werden, und dass 2. abgebrochen oder verzögert werden?!


----------



## SlaterB (4. Feb 2007)

bist du denn sicher dass das erste nicht klappt?

wenn das erste allein klappt wann klappt es nicht mehr?
wenn du Connection2 erzeugst?
wenn du Connection2 auf TRANSACTION_SERIALIZABLE setzt? 
usw, teste Zeile um Zeile was los, was wann warum und wieso passiert,

wenn du hier zum zweiten Mal nur schreibst 'ich weiß nicht was los ist', 
dann habe ich auch keine Lust mehr das alles Punkt um Punkt abzufragen..

meine Vermutung:
con1.executeUpdate("UPDATE konten SET kontostand = 5 WHERE kontonr = 1"); 
funktioniert tadellos
(testen, ob danach ein System.out.println ausgeführt wird)

der Befehl danach blockiert aber, er wartet bis die erste Verbindung committed,

ewiges Warten kann man evtl. noch durch setzen eines Timeouts verhindern,
dazu kann ich persönlich nix genaues sagen


----------

