edit
Software Transactional Memory
- Problem: Shared Mutable Memory
- Race Conditions möglich, explizite Synchronisation nötig
- Verantwortlichkeit des Entwicklers
- Software Transactional Memory (STM) ist deklarativ
- Keine Data Races, keine Deadlocks (Race Conditions noch möglich)
- In HW oder SW implementierbar
- HW-Support von Intel schon drin
- Frameworks für Java, Scala, .NET, ...
Software Transactions
- Kritische Sektionen identifizieren
- Drum herum
atomic {...}
(konzeptionell) schreiben
- R/W auf Speicher sind atomar
- Erfüllt ACI-Kriterien
- Kein "Durable" / Persistenz
- Isolations-Mechanismus wird System übergeben
- Seiteneffekte sind nicht isoliert (z.B. I/O)
- Implementiert meist mit Optimistic Concurency
- Unsynchronisiert ausführen, bei Konflikte Rollback und (automatic) Retry
- Pesimistic Concurrecy wäre wieder Deadlock-Gefahr
STM vs. Locking
- Unterschied zu Monitor Lock: Deskriptiv, es wird nicht gesagt, wie es isoliert werden soll
- Geschachtelte Transactions: Locking ist nicht deadlock-frei
Probleme
- Seiteneffekte sind immer sichtbar
- Wenn z.B. Netzwerkstream-losgeschickt wird, kann er schlecht "rollbacked" werden
- Starvation-Gefahr, wenn optimistic concurrency ständig retries macht
- Muss dann evtl. komplett seriell ausgeführt werden
- Bei Konflikten soll Transaktion direkt abgebrochen werden, sonst kann z.B. ein Runtimeerror (z.B. Division by 0) auftreten, weil die Transaktion optimistisch ausgeführt wird
Warten auf Bedingungen
retry
im atomic
-Block, um die Prüfung der Bedinung zu wiederholen
atomic
-Blocks könnten geschachtelt werden, um nur bestimmte Teile des Programms zu "retryen". Ist aber kontrovers
STM auf Java
- Bietet einen Wrapper für Transaktionen
- Sonst müssten Speicherzugriffe auf JVM-Ebene detektiert werden
- Variablen müssen eingepackt werden
final Ref.View<Integer> balance = STM.newRef(0);
- Datentyp muss immutable sein!
- Indirekte Strukturen (Collections) sind nicht transaktionell
- Explixit
STM.newMap()
etc. verwenden
- In Scala einfacher zu handhaben
void withdraw(int amount) {
STM.atomic(() -> {
if (balance.get() < amount) {
STM.retry();
}
balance.set(balance.get() - amount);
lastUpdate.set(LocalDate.now());
});
}
atomic
kann auch geschachtelt werden
- Wenn im Atomic-Block eine Exception geworfen wird, wird die Transaktion rollbacked und die Exception heraus geworfen
Write Skew Problem
- Problem bei "Snapshot Isolation": Anhand des Anfangsstatus werden Entscheidungen getroffen, so können Fehler auftreten (siehe Bsp. Folie)
- Darf in STM nicht passieren
- In Scala STM korrekt implementiert
- Bei anderen Systemen (z.B. auch Datenbanken), die einfache Snapshot Isolation verwenden
Starvation Problem
- Wenn Transaktionen ständig abgebrochen werden
- In Scala STM ist beliebige Wiederholung möglich