Wie kann ich denn einen Lock auf den Datensatz manuell setzen?
Code:
select * from gb_vw_proc_c_ord_payment where pcme_ord_id=12348167;
Das würde ein Lock auf den Datensatz (oder mehrere) setzen, wo das Kriterium zutrifft.
Es produziert also eine Sperre auf bestimmten Datensätzen, ohne überhaupt etwas zu ändern. Es macht also diese Sperre, weil der Ausführende explizit "freie Hand" haben möchte, um die Datensätze zu manipulieren und sie vor einer Änderung durch andere zu schützen (bis commit oder rollback)
Der Sperreffekt des Statementes oben ist der gleiche, wie der eines Updates, wie Du es gepostet hast.
Da es ein Testdatenbank ist, habe ich freie Hand
Das impliziert, dass niemand außer Dir Datensätze sperrt und damit die DB bzw. einen der Datensätze in einen Lock bringt.
Es muss also ein Programm laufen oder eine andere Sitzung (Session) von Dir, die zu dem Effekt führt.
Das ist ungewöhnlich und ist Dir ja scheinbar auch noch nie passiert, sonst wüsstest Du, was los ist.
Mögliche Ursachen:
- Ein Programm von Dir läuft parallel und hat das Update (nicht mit Commit) abgeschlossen
- Eine IDE oder ähnliches läuft und hat mit einem solchen Statement zu dem Zustand geführt
- irgendetwas hat dieses (oder mehr ) Statements ausgeführt und ist an ein Limit gelaufen
Limits
Ein mögliches Limit wäre eine größere Transaktion (Volumen bzw. Laufzeit wegen intensiver Berechnung / Mengenfindung), das noch nicht abgeschlossen ist oder durch seine Last ein anderes Limit erreicht hat. Ein konkretes Limit könnte z.B. Festplattenplatz (physikalisch) oder logischer Platz (Tablespace) sein oder Erweiterungsregeln für Tabellenspeicherbereich, die für das Statement nicht ausreichen.
Speichermangel, logisch oder physikalisch, kann gerne auf Testsystemen eintreten (naheliegend), die eben zum Test oder aus Kostengründen (Cloud) (zu) klein ausgelegt sind oder durch einen Programm oder Statementfehler künstlich (fehlerhaft) aufgebläht sind oder deren Platz (Gedächtnis) für die Verarbeitung einer großen Transaktion und das mögliche Rollback nicht groß genug sind.
Ein Zombieprozess hält Sperren und ist nicht ohne gezieltes Suchen erkennbar (GUI Fenster weg, Einzelprozess eines Programm Threads). Zombies entstehen durch Programmierfehler, Schedulefehler bei automatisierten Abläufen per Cron, Scheduled Task oder Oracle eigene Automatisierungsverfahren, die in einen Fehlerzustand laufen, überschneiden usw.
(Auto)Commit Verhalten
Ob Programmcode, IDE oder auch SQLplus (Command Line), alle diese Systeme können im Autocommit laufen. Das wäre nicht ungewöhnlich. Ein beliebiges Update Statement würde also automatisch commited und Dein Problem würde nie auftreten. (Und ein explizites Commit wäre sinnlos/unnötig)
Umgekehrt könntest Du bei einer hinreichend großen DB mit genügend Resourcen (Speicherplatz) und ausgeschaltetem Autocommit und der fortwährenden Nutzung einer einzigen(!), ununterbrochenen Sitzung tagelang Updates, Deletes und Inserts machen, ohne explizites Commit. Das geht vor allem dann, wenn jedes einzelne Statement logisch korrekt ist. Praktisch funktioniert das bspw. wenn Du ein Tutorial an Deinem Laptop durcharbeitest und das Teil abends einfach zu klappst und morgens wieder öffnest.
Erzwungenes Commit
Es wäre möglich, dass Dein System (andere Programmteile oder Scripte) durch irgendetwas explizite oder implizite Commits durchführen, ohne dass sie augenfällig sind. Jedes DDL Statement führt bei Oracle implizit zu einem Commit. Wird soetwas automatisiert durchgeführt, wird also ständig commited (ohne dass der Befehl explizit im Code auftaucht!). Bleibt dies aus, verhält sich das System vermutlich interaktiv anders, als sonst. Programme können explizite Commits enthalten (am schlimmsten in Stored Procs oder Functions). Ein simples Select einer solchen Funktion kann also fortwährend ein Commit verschleiern. Abhängig vom Verlauf einer Session (mit Aufruf einer solchen Funktion oder ohne), ist das Verhalten also vollkommen anders.
Abhängig von der Art bzw. Ursache des Commits geht es bei den aufgeführten Problemen um Effekte, die man interaktiv selbst provoziert hat oder die in einer anderen Sitzung ausgelöst werden.
Möglichkeiten
- Lock finden und löschen, also die Session beenden, die das Lock hält.
- Lock eingrenzen (zum Üben)
Du kannst andere Updates durchführen und ausprobieren, ob sie funktionieren. Lassen sich "Nachbardatensätze" aktualisieren? Damit kannst Du mglw. selbst eine Erklärung finden, was zu dem Lock führt.
Du wirst am ehesten selbst wissen, welches Szenario die Ursache sein könnte. Von hier aus ist es kaum zu erklären.