# Nebenläufigkeit kontrollieren in Postgres



## Kirby.exe (7. Jun 2021)

Also irgendwie bin ich sehr verwirrt...Wir sollen ein psql Skript "korrigieren" sodass die Nebenläufigkeit hier keine Probleme macht. Dazu wurde das "Schlüsselwort" SET TRANSACTION von Postgres genannt, jedoch verstehe ich nicht ganz wie der Kram funktioniert...Ich habe das so verstanden, dass man für jeden Thread eine Transaction erstellt und so gleichzeitigen Zugriff auf die selbe Tabelle verhindert. 

Jedoch vermute ich, dass dies falsch ist, denn mein Skript funktioniert nicht xD

```
PSQL='psql -U aphbr -h localhost -p 5435'

$PSQL -c 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;'
$PSQL -c 'DROP TABLE IF EXISTS t;'
$PSQL -c 'CREATE TABLE t (s NUMERIC);'
$PSQL -c 'INSERT INTO t VALUES (0);'

for i in ‘seq 1 100‘
do
    $PSQL -c 'BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; INSERT INTO t VALUES (1+(SELECT MAX(s) FROM t)); COMMIT TRANSACTION;' &
done
```

Hier ist der Link zu den Docs von Set Transactions


----------



## mihe7 (7. Jun 2021)

Die Zeile 3 ist natürlich für die Tonne. Du startest eine Session (psql), dort eine Transaktion und dann wird die Session beendet, womit auch die Transaktion beendet wird. Zeile 10 sieht besser aus, allerdings wird repeatable read nicht reichen. Werden die Anweisungen innerhalb eines kurzen Zeitraums ausgeführt, lesen mehrere Transaktion ggf. das gleiche Maximum aus der Tabelle.


----------



## Kirby.exe (7. Jun 2021)

mihe7 hat gesagt.:


> allerdings wird repeatable read nicht reichen. Werden die Anweisungen innerhalb eines kurzen Zeitraums ausgeführt, lesen mehrere Transaktion ggf. das gleiche Maximum aus der Tabelle.


Ehm was sollte ich denn dann verwenden? Serialable oder wie des heißt? xD


----------



## mihe7 (7. Jun 2021)

Kirby.exe hat gesagt.:


> Ehm was sollte ich denn dann verwenden? Serialable oder wie des heißt? xD


Lesen, lesen, lesen...


----------



## Kirby.exe (7. Jun 2021)

Also ich habe jetzt echt lange rumprobiert und habe wirklich keine Idee xD


----------



## mihe7 (7. Jun 2021)

Funktioniert SERIALIZABLE nicht?!?


----------



## Kirby.exe (7. Jun 2021)

mihe7 hat gesagt.:


> Funktioniert SERIALIZABLE nicht?!?


Nope da kommt ne saftige Fehlermeldung


```
kirby@kirby: ./scripty.sh
SET
DROP TABLE
CREATE TABLE
INSERT 0 1
kirby@kirby:$ ERROR:  could not serialize access due to read/write dependencies among transactions
DETAIL:  Reason code: Canceled on identification as a pivot, during commit attempt.
HINT:  The transaction might succeed if retried.
ERROR:  could not serialize access due to read/write dependencies among transactions
DETAIL:  Reason code: Canceled on identification as a pivot, during write.
HINT:  The transaction might succeed if retried.
COMMIT
```

Hier nochmal der Code :


```
PSQL='psql -U aphbr -h localhost -p 5435'

$PSQL -c 'SET STATEMENT_TIMEOUT = 600000;'
$PSQL -c 'DROP TABLE IF EXISTS t;'
$PSQL -c 'CREATE TABLE t (s NUMERIC);'
$PSQL -c 'INSERT INTO t VALUES (0);'

for i in ‘seq 1 100‘
do
    $PSQL -c 'BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; INSERT INTO t VALUES (1+(SELECT MAX(s) FROM t)); COMMIT TRANSACTION;' &
done
```


----------



## mihe7 (7. Jun 2021)

Das ist doch richtig. Du hast keine doppelten Werte in der Tabelle, die betreffenden Transaktionen schlagen fehl (ACID-Eigenschaft). Wenn Du willst, dass das einfach durchläuft, dann würde ich Sperren verwenden, also vor dem INSERT noch ein `LOCK TABLE t;` einfügen.


----------



## Kirby.exe (7. Jun 2021)

Ist das normal, dass des so lange läuft xD


----------



## mihe7 (7. Jun 2021)

Kirby.exe hat gesagt.:


> Ist das normal, dass des so lange läuft xD


Was heißt lange? Drück mal Return


----------



## Kirby.exe (7. Jun 2021)

mihe7 hat gesagt.:


> Was heißt lange? Drück mal Return


Wenn ich Return drücke wird abgebrochen und es werden irgendwie auch nur Werte 1,2,3 reingeschrieben xD Wo sind meine restlichen 97 Einträge xD


----------



## mihe7 (8. Jun 2021)

Warte mal, ich probier das mal aus.


----------



## mihe7 (8. Jun 2021)

So:


Spoiler: Ergebnis





```
SET
DROP TABLE
CREATE TABLE
INSERT 0 1
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT
COMMIT

real    0m1.267s
user    0m4.035s
sys    0m2.286s
```






Spoiler: Skript



PSQL='psql -U postgres'

$PSQL -c 'SET STATEMENT_TIMEOUT = 600000;'
$PSQL -c 'DROP TABLE IF EXISTS t;'
$PSQL -c 'CREATE TABLE t (s NUMERIC);'
$PSQL -c 'INSERT INTO t VALUES (0);'

for i in $(seq 1 100)
do
    $PSQL -c 'BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; LOCK TABLE t; INSERT INTO t VALUES (1+(SELECT MAX(s) FROM t)); COMMIT TRANSACTION;' &
done

wait $(jobs -p)



Das läuft bei mir in einem Docker-Container.


----------



## Kirby.exe (8. Jun 2021)

Jetzt gehts xD WTF kp woran es lag xD


----------



## mihe7 (8. Jun 2021)

Vermutlich: $(seq 1 100) statt `seq 1 100`; letzteres wurde bei mir als String verarbeitet, d. h. für "seq", "1" und "100" wurde je eine Iteration durchgeführt - das würde dann auch die 3 Datensätze erklären.


----------



## Kirby.exe (8. Jun 2021)

mihe7 hat gesagt.:


> Vermutlich: $(seq 1 100) statt `seq 1 100`; letzteres wurde bei mir als String verarbeitet, d. h. für "seq", "1" und "100" wurde je eine Iteration durchgeführt - das würde dann auch die 3 Datensätze erklären.


bruh xD ich sollte echt meine bash kenntnisse verbessern xD des stand so auf dem PDF xD Ich dachte mhh wird schon stimmen xD 

Was lernt man daraus...Was man nicht kennt wird bei Google reingehackt xD


----------

