ERLEDIGT
NEIN
NEIN
ANTWORTEN
2
2
ZUGRIFFE
7487
7487
EMPFEHLEN
-
23.08.05 21:52 #1Aber gerne dochWie wärs denn mal mit einem "Tutorial" zum Thema locking in Oracle?
Row-Level Locking
Table Level Locking
Select for update
Deadlock
Wie findet man heraus wer welche Tabelle/Zeile gelockt hat und wie sieht man wer auf die Freigabe des Locks wartet...
Locking ist eines der entscheidenden Verfahren um das ACID Prinzip von Transaktionen in Datenbanken zu wahren. ACID steht hierbei für Atomicity, Consistency, Isolation und Durability. Eine Transaktion muss also Isoliert von allen anderen Transaktionen laufen, sie dürfen sich nicht gegenseitig beeinflussen. Ausserdem muss der Zustand der Daten nach einer Transaktion Konsistent sein, es dürfen keine Regeln der Datenbank (Datenlogik) verletzt werden.
Locking dient vor allem zur Isolation der Transaktion und verhindert, dass sich Benutzer durch den gleichzeitigen Zugriff auf die selben Resourcen stören.
Will ein Benutzer also einen Datensatz manipulieren, schliesst danach jedoch seine Transaktion nicht ab, so darf der Datensatz solange von keinem anderen Benutzer geändert werden. Es würde in die Transaktion vom 1. Benutzer eingreifen.
Demo:
Bert hat also einen Satz upgedated und somit gelockt. Wenn Erni versucht ihn zu lesen mit dem Anhang "for Update" erbittet Erni von der Datenbank ebenfalls einen Lock um den Datensatz zu editieren, dieser ist jedoch schon gelockt und somit erscheint nach 5 Sekunden (wait 5) eine Fehlermeldung. Ein "normaler" Select funktioniert noch, zeigt Erni aber den ursprünglichen Datenbestand der Tabelle, und zwar so lange wie Bert seine Transaktion nicht commited hat.Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
User1: SQL> conn bert/bert Connected. SQL> select * from lock_tes; FIELD1 FIELD2 ---------- ---------- 1 Feld1 2 Feld 2 3 Feld 3 SQL> update lock_tes set field1=4 where field1=3; 1 row updated. ----- User2: SQL> conn erni/erni Connected. SQL> select * from bert.lock_tes for update wait 5; select * from bert.lock_tes for update wait 5 * ERROR at line 1: ORA-30006: resource busy; acquire with WAIT timeout expired SQL> select * from bert.lock_tes; FIELD1 FIELD2 ---------- ---------- 1 Feld1 2 Feld 2 3 Feld 3 SQL> update bert.lock_tes set field2='Test' where field1=1; 1 row updated.
Das ganze nennt man nun Row Level Locking, da der Lock nur auf dem einzelnen Datensatz liegt, man sieht am zweiten Update, dass es mit einem anderen Datensatz problemlos funktioniert.
Das schlimmste was ein Anwendungsentwickler produzieren kann sind sog. Full Table Locks. Das bedeutet jeder Satz der Tabelle ist gesperrt, was schonmal eine komplette Applikation lahm legen kann... Daher Updates möglichst in kleinen Transaktionen und möglichst rasch abschliessen!
Ein Table Level Locking (bzw, Object Level Locking) tritt meistens dann auf, wenn DDL Statements auf das Objekt wirken. Denkbar wäre z.B. das verschieben einer Tabelle in ein anderes Datenfile, der Neuaufbau einen Indizes etc. In diesem Fall ist das komplette Objekt für den Benutzerzugriff gesperrt. Zusätzlich gibt es noch DDL Locks. Diese verhindern z.B. das Droppen einer Tabelle falls gerade eine View erstellt (kompiliert wird) welche auf diese Tabelle zugreift.
Erfahrungsgemäss ist das Lockingverfahren von Oracle sehr sehr gut und alle mir bisher bekannten Probleme rühren von schlechter Entwicklung. Einer der gravierensten Fehler, nämlich ein "unsortierter" Zugriff auf Objekte führt bei stark genutzten Applikationen ständig zu Deadlocks:
Oracle erkennt zum Glück den Deadlock und bricht eine der Transaktionen ab und rollt sie zurück.Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Erni: SQL> UPDATE bert.lock_tes set field2='Test2' where field1=1; 1 row updated. Bert: SQL> update lock_tes set field2='Test3' where field1=2; 1 row updated. Erni: SQL> update bert.lock_tes set field2='Testbla' where field1=2; ... Transaktion wartet, wegen Lock von Bert... Bert: SQL> update lock_tes set field2='djkfh' where field1=1; ... Transaktion wartet, wegen Lock von Erni... Erni: update bert.lock_tes set field2='Testbla' where field1=2 * ERROR at line 1: ORA-00060: deadlock detected while waiting for resource
Auf welchem Objekt gerade ein Lock sitzt, und ob und wer gerade darauf wartet, kann man aus mehreren Tabellen im Data Dictionary lesen.
Einen guten Einstieg gibt die Tabelle DBA_BLOCKERS. Sie liefert die SessionID der User, die andere User blockieren. Die SessionID kann man widerum in der v$Session Abfragen und somit den User, den Host und die Applikation ermitteln.
Auch V$SESSION_WAIT ist gut, sie zeigt wartende Benutzer.
DBA_DML_LOCKS zeigt alle DML Locks in der Datenbank. Noch etwas genauer, wenn man z.B. die gelockte Zeile ermitteln will, ist jedoch die View v$Lock, wenn auch etwas kompliziert zu lesen.
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
SQL> select * from v$lock where sid in ( select sid from v$session where username <> 'ORACLE'); ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK -------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ---------- 29E1957C 29E19590 39 TX 327698 298 0 6 852 0 292BC6F4 292BC70C 39 TM 52533 0 3 0 852 0 292BC7A0 292BC7B8 49 TM 52533 0 3 0 1143 0 292D7620 292D773C 49 TX 327698 298 6 0 1143 1 SQL> select sid, username from v$session where sid in (39, 49); SID USERNAME ---------- ------------------------------ 39 ERNI 49 BERT SQL> SELECT Owner, Object_type, object_name from dba_objects where object_id = 52533 OWNER OBJECT_TYPE OBJECT_NAME ------------------------------ ------------------- -------------------- BERT TABLE LOCK_TES
Eine hübsche Methode den Datensatz zu bekommen:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Wir nehmen die SID der geblockten Session (siehe v$lock): SQL> SELECT SID, ROW_WAIT_OBJ#, ROW_WAIT_FILE#, ROW_WAIT_BLOCK#, ROW_WAIT_ROW# FROM V$SESSION WHERE SID = 49; SID ROW_WAIT_OBJ# ROW_WAIT_FILE# ROW_WAIT_BLOCK# ROW_WAIT_ROW# ---------- ------------- -------------- --------------- ------------- 49 52533 4 404 1 ... ermitteln den Namen des Objekts (über DBA_OBJECTS) und fragen die Zeile mit der gesuchten ROWID ab: SQL> SELECT * FROM BERT.LOCK_TES WHERE ROWID = DBMS_ROWID.ROWID_CREATE(1, 52533, 4, 404, 1); FIELD1 FIELD2 ---------- ---------- 2 Test3 Tada ;-)
Allgemein kann man sagen, dass Locking ein sehr schwieriges Thema ist. Schon alleine die Theroie über Isolation Levels etc.. würde den Rahmen hier bei weitem sprengen. Dennoch sollte aber jeder Entwickler zumindest das ACID Prinzip verstanden haben und wissen worauf es in seinem verwendeten RDBMS ankommt um es erfolgreich umzusetzen. Ich muss zugeben, dass mir oft auch nie ganz klar wird wann Oracle welchen Lock setzt und was dann noch alles erlaubt wird, in so einem Fall hilft eben einfach nur ausprobieren.
Ums Testen kommt man sowieso nicht drum rum, denn spätestens bei einem Versionswechsel kann sich das Locking Verhalten wieder ändern. Seit Oracle 9 gibt es auch schöne Features wie "ALTER INDEX REBUILD ONLINE". Dies verhindert z.B. ein kompletten Lock des Indizes so dass dieser weiterhin benutzt werden kann, bis er an anderer Stelle komplett neu aufgebaut wurde. (Kann bei sehr großen Tabellen durchaus Sinn machen)
Soviel erstmal zum Thema Locking. Im Moment wüsste ich nicht was ich dazu noch erklären könnte ohne zu tief einzusteigen ?!liebe Grüße
Exceptionfault (http://exceptionfault.de)
Never say: "Always"! Always say: "Never say never"! - Tom Kyte @ Ask Tom Live in Berlin 2008
-
23.08.05 22:28 #2
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.724
- Blog-Einträge
- 29
Hallo!
wiedermal wunderbar gemacht
Wie wär's mit noch nem tutorial zum Thema DB-Links in Oracle? *g*
//Edit:
Ich sehe es schon vor mir... bald brauchen wir wirklich sowas wie einen
askandreas.tutorials.de - Corner
Gruß TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
Auch von mir ein großes DANKE *lob*
Werd' bei einer Gelegenheit mal versuchen, das in der Praxis nachzuvollziehen, kann sein, dass ich dann noch Fragen hab
Klingt so aber erstmal alles einleuchtend.
Nochmal ein großes DANKEGrüße Nico
----------------------
Xing
----------------------
Zitat von Mark Twain (1835-1910)
Zitat von Mike Wilson - Biographie über Larry Ellison (CEO Oracle)
Ähnliche Themen
-
[C] d´Hondt-Verfahren / Höchstzahlen-Verfahren - Höchstwerte eines mehrdim. Arrays
Von Info-Stud2010 im Forum C/C++Antworten: 0Letzter Beitrag: 16.12.09, 18:11 -
[ORACLE] Demo: Datenbanklinks
Von Exceptionfault im Forum Relationale DatenbanksystemeAntworten: 6Letzter Beitrag: 12.02.09, 12:48 -
Annotation für Pessimistisches Locking
Von AliB im Forum Enterprise Java (JEE, J2EE, Spring & Co.)Antworten: 0Letzter Beitrag: 08.10.07, 13:40 -
Record Locking Problem
Von marcel_m im Forum Relationale DatenbanksystemeAntworten: 12Letzter Beitrag: 29.03.07, 11:30 -
[ORACLE] Demo: Sicherheit auf Zeilenebene
Von Exceptionfault im Forum Relationale DatenbanksystemeAntworten: 3Letzter Beitrag: 23.08.05, 20:09





Zitieren


Login




