fix(quick-260909-jts): Lastprobe nachreichen statt sie zu behaupten

This commit is contained in:
2026-09-09 15:18:55 +02:00
parent abb6c8bea3
commit 604428a91d
3 changed files with 134 additions and 20 deletions
+18 -11
View File
@@ -75,13 +75,9 @@ import { PrismaClient } from '@prisma/client';
* der aeusseren Transaktion ist nicht mehr gegeben.
* Form (ii) — interaktive Callback-Form auf dem gebundenen Client
* (`forTenant(prisma, tenantId).$transaction(async (tx) => ...)`):
* bestand die Einzelmessung (gleiche Verbindung, richtiger
* Kontext, richtige Zeilenzahl), brach aber unter einer
* zusaetzlichen Lastprobe (40 parallele Aufrufe,
* alternierend TENANT-A/TENANT-B) mit
* `PrismaClientKnownRequestError: Transaction API error:
* Unable to start a transaction in the given time.` (P2028)
* ab — jeder `tx.$queryRaw`-Aufruf innerhalb der interaktiven
* besteht die Einzelmessung (gleiche Verbindung, richtiger
* Kontext, richtige Zeilenzahl), faellt aber unter Last aus.
* Ursache: jeder `tx`-Aufruf innerhalb der interaktiven
* Transaktion loest selbst wieder eine VERSCHACHTELTE
* Array-Transaktion aus (weil `$allOperations` bei jedem
* Aufruf erneut feuert), und die aeussere plus jede innere
@@ -89,10 +85,21 @@ import { PrismaClient } from '@prisma/client';
* demselben, endlichen Pool.
* Form (iii) — interaktive Callback-Form auf dem UNGEBUNDENEN Client,
* `set_config` als ERSTE Anweisung direkt auf `tx` (nicht auf
* dem aeusseren Client): bestand sowohl die Einzelmessung als
* auch die Lastprobe (0 Verletzungen unter 40 parallelen
* Aufrufen) — sie belegt pro Aufruf genau EINE Verbindung,
* ohne Verschachtelung.
* dem aeusseren Client): besteht Einzelmessung UND Lastprobe —
* sie belegt pro Aufruf genau EINE Verbindung, ohne
* Verschachtelung.
*
* Die Lastprobe steht als `runConcurrencyProbe` in
* `apps/api/scripts/rls-scratch-check.mjs` und ist jederzeit wiederholbar:
* 40 gleichzeitige Aufrufe ueber EINEN Client, abwechselnd fuer zwei
* Mandanten. Gepruft wird nur die Eigenschaft, auf die dieser Code sich
* stuetzt — Form (iii) ohne Verletzung; Form (ii) laeuft daneben als
* ausgedruckte Beobachtung mit, weil ihr Bruchpunkt an Verbindungsvorrat
* und Maschine haengt und deshalb keine Bedingung fuer einen gruenen Lauf
* sein darf. Die konkreten Zahlen eines Laufs stehen daher NICHT hier,
* sondern fallen bei jeder Ausfuehrung neu an. Diese Probe wurde
* nachgereicht: die Aussage stand zunaechst nur als Fliesstext hier, ohne
* dass sie jemand haette nachvollziehen koennen.
*
* Entscheidung: `withTenantTransaction()` unten baut Form (iii) nach und
* ist das Hilfsmittel fuer alle mehrschrittigen, mandantengebundenen