programmera.net -> oracle -> normal för utskrift | info@programmera.net |
Pessimistisk låsning i Oracle
1. Vad är pessimistisk låsning? 2. Steg1: Användare A söker fram Ford 3. Steg2: Användare B misslyckas med att söka fram Ford 4. Steg3: Användare A uppdaterar lönen för Ford |
1. Vad är pessimistisk låsning?
Pessimistisk låsninging innebär att man låser raden i tabellen i samband med framsökningen av data. Under tiden från att raden är låst fram till och med att UPDATE utförs kan ingen annan uppdatera den aktuella raden. Denna metod är mycket bra men har följande nackdel:
På 90-talet då det var vanligt med client/server-applikationer fungerade pessimistisk låsning bra. Idag då tunna klienter är vanliga behåller en användare i princip aldrig samma databasuppkoppling mellan olika anrop mot servern. Därför är pessimistisk låsning en något utdaterad lösning för problemet med förlorad uppdatering. Hur som helst, bilden nedan visar ett exempel på hur pessimistisk låsning fungerar:
Stegen beskrivs översiktligt nedan:
Nedan beskrivs stegen i detalj:
2. Steg1: Användare A söker fram Ford
Klockan 13:22:52 loggar användare A in på applikationen för att uppdatera data för en anställd vid namn "Ford" (som lagras i tabellen EMP). A söker fram "Ford" genom att använda siffran 7902 som är Fords anställningsnummer. Anta att den webbsida som visas efter sökningen ser ut såhär:
Vi simulerar själva sökningen i SQL*Plus genom att köra följande SELECT-sats:
SQL> SELECT * FROM emp WHERE empno=7902 FOR UPDATE NOWAIT;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- ---------- ---------- ---------- ----------
7902 FORD ANALYST 7566 1981-12-03 3000 20
3. Steg2: Användare B misslyckas med att söka fram Ford
Klockan 13:25:16 vill användare B, som använder samma applikation, också uppdatera data för "Ford". B söker fram "Ford" på samma sätt som A men kommer att mötas av ett felmeddelande.
Vi simulerar denna sökning genom att öppna ett nytt terminalföster (eller MSDOS-fönster) och loggar in i SQL*Plus och kör samma SELECT-sats:
Vi ser att vi möts av ett "ORA-00054" som indikerar att raden är låst.
SQL> SELECT * FROM emp WHERE empno=7902 FOR UPDATE NOWAIT;
SELECT * FROM emp WHERE empno=7902 FOR UPDATE NOWAIT
*
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified
4. Steg3: Användare A uppdaterar lönen för Ford
Klockan 13:26:31 bestämmer sig användare A (efter att ha stirrat på data för Ford i c.a. 4 minuter) för att uppdatera Fords lön från 3000 till 3200, se bild:
När A ny trycker på SUBMIT kommer samtliga data i formuläret skickas till databasen. Vi utgår från att applikationen alltid uppdaterar samtliga kolumner då man utför en UPDATE. Alltså ENAME sätts till "Ford" trots att det redan var "Ford" tidigare osv. För att simulera detta ska du utföra SQL-satsen nedan i den första SQL*Plus-terminalen:
Nu ska det funka.
SQL> UPDATE emp SET ename='FORD', job='ANALYST', mgr=7566, sal=3200 WHERE empno=7902;
1 row updated.
SQL> COMMIT;
Commit complete.