Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

PL/SQL & T-SQL (Oracle and SQL Server)  Module 15 – Production PL/SQL: staging, concurrency, JSON and tests

Row locks, SKIP LOCKED and scheduler jobs

Read committed data while rows are locked, take row locks with NOWAIT, WAIT or SKIP LOCKED, stop lost updates and run work as scheduler jobs.

  • Advanced
  • 20 minutes
  • Examples run with oracle-free 23.26.3.0.0, mssql 17.0.5005.3, Python 3.14.8 and Pyodide 314.0.7
  • By MySmartCoPilot
Free core, Pro depth: 7 of 20 minutes free
Free: Readers see committed data while a writer holds the row · Row locks: wait, NOWAIT, WAIT n or SKIP LOCKED. With a pass: 3 in-depth parts and 3 interview answers, about 13 minutes.

What you will learn

  • Explain Oracle's multiversion read consistency
  • Choose between waiting, NOWAIT, WAIT n and SKIP LOCKED for a locked row
  • Prevent lost updates with optimistic checks
  • Run background work with DBMS_SCHEDULER

Before you start

Three workers take payment jobs from one queue table of six jobs. Without row locks two of them can take the same job and send one payment twice; with a plain FOR UPDATE the second worker waits for the first; with SKIP LOCKED each takes a different job at once.

You will see why a reader in Oracle never waits for a writer, choose what a session does when it meets a locked row, and meet the tools that put row locks to work: a shared job queue, checks that stop lost updates, scheduler jobs that run work in the background, and a way to change one busy number without row locks.

Readers see committed data while a writer holds the row

Oracle’s Concepts guide states the rules in four lines. A row is locked only when a writer changes it, or when SELECT ... FOR UPDATE asks for its lock. A writer blocks another writer of the same row. Queries and writers, though, never hold each other up: while a row is being changed, the database uses undo data to give each query the version that was last committed. That is read consistency: The guarantee that a query sees data as committed at one point in time. While a row is being changed, Oracle builds its last committed version from undo data, so readers never wait for writers., and every query gets it for a single point in time, so its rows all come from one committed state.

Follow two sessions through the queue table pay_jobs, where job 1 holds the amount 100:

Interactive · message by message Two sessions and one locked row Step through steps 2 to 6 of for_update_choices.sql. Watch which statement waits and which does not.
Two sessions and one locked row, step 7 of 7. Messages so far: Session A to Database: UPDATE 1; Session B to Database: SELECT 1; Database to Session B: 100; Session A to Database: lock 1, 2; Session B to Database: lock all; Session A to Database: COMMIT; Database to Session B: rows 1-6.Session AwriterDatabaseB holds allSession BreaderUPDATE 1SELECT 1100lock 1, 2lock allCOMMITrows 1-6

The drawing shows the whole scene; its 7 steps are listed below.

Every step as text
  1. A changes job 1. Session A sets job 1's amount to 999 and does not commit. The row is now locked by A's transaction.
  2. B reads job 1. Session B runs a plain SELECT of job 1. A query takes no row lock, so it does not wait for A.
  3. B gets the committed value. The database builds the row as it was at the last commit, from undo data, so B sees the amount 100, not A's 999.
  4. A rolls back, then locks. Session A rolls back its change, then runs SELECT ... FOR UPDATE on jobs 1 and 2, which locks both rows until A's transaction ends.
  5. B asks to lock every job. Session B runs SELECT ... FOR UPDATE on all new jobs with no wait clause. Jobs 1 and 2 are locked, so B waits.
  6. A commits. Session A commits. Its row locks are released, and the database lets B's statement go on.
  7. B gets every job. B's statement returns jobs 1 to 6, and B now holds their row locks until it commits or rolls back.

Session B’s plain SELECT returned at once with the committed 100 while A’s 999 was still uncommitted. B’s SELECT ... FOR UPDATE waited, because it asked for row locks that A held. Waiting belongs to locks, never to reading.

Checkpoint

Check: Readers that never wait for writers

  1. Question 1 of 2 Session A has updated a row and not committed. What does session B's plain SELECT of that row do?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: Returns at once with the last committed value

    Oracle's Concepts guide: a reader never blocks a writer and a writer never blocks a reader, because the reader gets the committed version from undo data.

  2. Question 2 of 2 Session A has updated row 7 and not committed. Session B runs UPDATE on row 7. What happens?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: B waits until A commits or rolls back, then goes on

    Row locks exist to stop two writers of the same row; the second one waits for the first transaction to end.

Row locks: wait, NOWAIT, WAIT n or SKIP LOCKED

SELECT ... FOR UPDATE locks the rows it selects until the transaction ends, so no other session can change or lock them first. Oracle’s SELECT page allows it only in a top-level query, not with DISTINCT, set operators, GROUP BY or aggregate functions. What a session does when it meets row locks held by another transaction depends on one clause:

Clause When a selected row is locked by another transaction
none waits until that transaction commits or rolls back
NOWAIT fails at once with ORA-00054
WAIT 2 waits up to 2 seconds, then fails if the row is still locked (in the lab run, with ORA-00054 too)
SKIP LOCKED leaves that row out, and locks and returns the others

WAIT counts seconds unless MILLISECONDS or MICROSECONDS follows the number. SKIP LOCKED is built, in the SELECT page’s words, for multiconsumer queues: each consumer skips the rows other consumers hold and gets the remaining rows without waiting. The lab script runs every clause in two windows, and the model prints what session B gets while A holds jobs 1 and 2. Press Edit, set HELD = [1, 2, 3, 4, 5, 6] and run it again:

for_update_choices.sql: a reader, a writer and four FOR UPDATE clauses in two windows SQL · locks/for_update_choices.sql
-- Engine: Oracle AI Database 26ai Free, Release 23.26.3.0.0; user LAB in FREEPDB1. Client: two SQL*Plus or SQLcl
-- windows, A and B, both connected as LAB. Run each numbered step in the window it names, in order.
-- Step 1 creates the queue table pay_jobs with six new jobs. The steps then show a reader that does not wait for a
-- writer, and what B gets from SELECT ... FOR UPDATE with each wait clause while A holds jobs 1 and 2.
-- claim_model.py prints the same outcomes. The last step drops the table.

-- 1. Window A: the queue table.
DROP TABLE IF EXISTS pay_jobs PURGE;
CREATE TABLE pay_jobs (
  job_id     NUMBER(10)   CONSTRAINT pay_jobs_pk PRIMARY KEY,
  amount     NUMBER(14, 2) NOT NULL,
  status     VARCHAR2(10) DEFAULT 'new' NOT NULL
             CONSTRAINT pay_jobs_status_ck CHECK (status IN ('new', 'running', 'done', 'failed')),
  attempts   NUMBER(3)    DEFAULT 0 NOT NULL,
  claimed_by VARCHAR2(30)
);
INSERT INTO pay_jobs (job_id, amount) SELECT LEVEL, 100 * LEVEL FROM dual CONNECT BY LEVEL <= 6;
COMMIT;

-- 2. Window A: change job 1 and do not commit.
UPDATE pay_jobs SET amount = 999 WHERE job_id = 1;

-- 3. Window B: a plain query returns at once and reads the committed amount.
SELECT job_id, amount FROM pay_jobs WHERE job_id = 1;
-- Expected: 1, 100. A writer never blocks a reader; the reader sees the last committed value.

-- 4. Window A: undo the change, then lock jobs 1 and 2 for this transaction.
ROLLBACK;
SELECT job_id FROM pay_jobs WHERE job_id IN (1, 2) FOR UPDATE;

-- 5. Window B: each statement meets the two locked rows.
SELECT job_id FROM pay_jobs WHERE status = 'new' ORDER BY job_id FOR UPDATE NOWAIT;
-- Expected: ORA-00054 at once.
SELECT job_id FROM pay_jobs WHERE status = 'new' ORDER BY job_id FOR UPDATE WAIT 2;
-- Expected: about 2 seconds pass, then the statement fails because the rows are still locked.
SELECT job_id FROM pay_jobs WHERE status = 'new' ORDER BY job_id FOR UPDATE SKIP LOCKED;
-- Expected: 3, 4, 5 and 6, now locked by B as well.
ROLLBACK;
SELECT job_id FROM pay_jobs WHERE status = 'new' ORDER BY job_id FOR UPDATE;
-- Expected: B waits. Go to window A.

-- 6. Window A: end the transaction. B's waiting statement returns 1 to 6 at once.
COMMIT;

-- 7. Window B: release the rows, then drop the table.
ROLLBACK;
DROP TABLE pay_jobs PURGE;
for_update_choices.sql, run in the lab Python · for_update_choices_session.py
"""for_update_choices.sql in the lab, in two SQL*Plus clients of LAB, A and B, step by step as the script
numbers them. Step 5 ends with a statement that waits for A's locks; its rows arrive after A's COMMIT in
step 6. The lock error names a transaction by numbers that change on every run, shown as <n>."""

from oracle_session import Lab

STEP = r"^-- \d+\. (?P<who>Window A|Window B|Both windows|Clean-up)\b"
WHO = {"Window A": ["A"], "Window B": ["B"], "Both windows": ["A", "B"], "Clean-up": ["A"]}
MASKS = [(r'by \d+ \("usn<<16 \| slot"\)', 'by <n> ("usn<<16 | slot")'), (r'and \d+ \("sequence"\)', 'and <n> ("sequence")'),
         (r"transaction ID(\s+)\d+\.\d+\.\d+", r"transaction ID\1<n>.<n>.<n>")]

with Lab(masks=MASKS) as lab:
    lab.steps("locks/for_update_choices.sql", STEP, WHO, users={"A": "lab", "B": "lab"}, waiting={5}, errors=2)

Output

A> 1. Window A: the queue table.
Table dropped.


Table created.


6 rows created.


Commit complete.

A> 2. Window A: change job 1 and do not commit.
1 row updated.

B> 3. Window B: a plain query returns at once and reads the committed amount.
    JOB_ID     AMOUNT
---------- ----------
         1        100

A> 4. Window A: undo the change, then lock jobs 1 and 2 for this transaction.
Rollback complete.


    JOB_ID
----------
         1
         2

B> 5. Window B: each statement meets the two locked rows.
SELECT job_id FROM pay_jobs WHERE status = 'new' ORDER BY job_id FOR UPDATE NOWAIT
                   *
ERROR at line 1:
ORA-00054: Failed to acquire a lock (Type: "TX", Name: "Transaction",
Description: "Lock held by a transaction to allow other transactions to wait
for it") because it is currently held by another session. The resource being
locked can be identified by <n> ("usn<<16 | slot") and <n> ("sequence")
ORA-40097: Failure to acquire row lock, currently held by transaction ID
<n>.<n>.<n>
Help: https://docs.oracle.com/error-help/db/ora-00054/


SELECT job_id FROM pay_jobs WHERE status = 'new' ORDER BY job_id FOR UPDATE WAIT 2
                   *
ERROR at line 1:
ORA-00054: Failed to acquire a lock (Type: "TX", Name: "Transaction",
Description: "Lock held by a transaction to allow other transactions to wait
for it") because it is currently held by another session. The resource being
locked can be identified by <n> ("usn<<16 | slot") and <n> ("sequence")
ORA-40097: Failure to acquire row lock, currently held by transaction ID
<n>.<n>.<n>
Help: https://docs.oracle.com/error-help/db/ora-00054/



    JOB_ID
----------
         3
         4
         5
         6


Rollback complete.
(B waits)

A> 6. Window A: end the transaction. B's waiting statement returns 1 to 6 at once.
Commit complete.

B> (the statement that waited returns)
    JOB_ID
----------
         1
         2
         3
         4
         5
         6

6 rows selected.

B> 7. Window B: release the rows, then drop the table.
Rollback complete.


Table dropped.

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 for_update_choices_session.py

What session B gets from each FOR UPDATE clause, modelled in Python Python · model/claim_model.py
"""What a second session gets from SELECT ... FOR UPDATE while a first session holds row locks, modelled in Python.

A model, not Oracle: it applies the rules of Oracle's SELECT page and its Concepts guide. A row is locked only by a
writer or by SELECT ... FOR UPDATE, and the lock lasts until that transaction commits or rolls back. Without a wait
clause the second session waits; NOWAIT fails at once with ORA-00054; WAIT n waits up to n seconds, then fails; SKIP
LOCKED returns and locks the rows nobody else holds. A plain query, without FOR UPDATE, never waits.

Press Edit, change HELD (the jobs session A holds), and run it again.
"""

JOBS = [1, 2, 3, 4, 5, 6]          # payment jobs with status 'new'
HELD = [1, 2]                      # session A: SELECT ... WHERE job_id IN (1, 2) FOR UPDATE, not committed

free = [job for job in JOBS if job not in HELD]
print(f"Session A holds jobs {', '.join(map(str, HELD)) or 'none'} with FOR UPDATE and has not committed.")
print("Session B runs SELECT job_id FROM pay_jobs WHERE status = 'new' ORDER BY job_id ...")
print()
rows = [
    ("without FOR UPDATE", f"returns {', '.join(map(str, JOBS))} at once, and locks nothing"),
    ("FOR UPDATE", "waits until session A commits or rolls back" if HELD else f"returns and locks {', '.join(map(str, JOBS))}"),
    ("FOR UPDATE NOWAIT", "fails at once with ORA-00054" if HELD else f"returns and locks {', '.join(map(str, JOBS))}"),
    ("FOR UPDATE WAIT 2", "waits 2 seconds, then fails: the rows are still locked" if HELD else f"returns and locks {', '.join(map(str, JOBS))}"),
    ("FOR UPDATE SKIP LOCKED", f"returns and locks {', '.join(map(str, free))}" if free else "returns no row at once"),
]
for clause, outcome in rows:
    print(f"  {clause:<24} {outcome}")
done = True

Output

Session A holds jobs 1, 2 with FOR UPDATE and has not committed.
Session B runs SELECT job_id FROM pay_jobs WHERE status = 'new' ORDER BY job_id ...

  without FOR UPDATE       returns 1, 2, 3, 4, 5, 6 at once, and locks nothing
  FOR UPDATE               waits until session A commits or rolls back
  FOR UPDATE NOWAIT        fails at once with ORA-00054
  FOR UPDATE WAIT 2        waits 2 seconds, then fails: the rows are still locked
  FOR UPDATE SKIP LOCKED   returns and locks 3, 4, 5, 6

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 claim_model.py

When every job is held, SKIP LOCKED returns no row at once, which a worker reads as “nothing to do now”. In 26ai the error pages also describe ORA-40097, which names the transaction holding a row lock by its undo segment, slot and wrap numbers.

Four larger topics follow from these row locks. A SKIP LOCKED: A clause of SELECT ... FOR UPDATE that leaves out the rows another transaction has locked and locks and returns the others, so several consumers of a queue can work without waiting for each other. queue lets several workers share one table of jobs without taking any job twice. A lost update: A change that disappears because another session, starting from an older read of the same row, writes over it. Both statements succeed, and no error is raised. is a change that another session overwrites from an older read, and an optimistic locking: A way to prevent lost updates that holds no lock between reading a row and writing it: the write itself checks that the row has not changed since it was read. in the UPDATE stops it. scheduler job: A job of Oracle Scheduler, created with DBMS_SCHEDULER.CREATE_JOB, that runs PL/SQL or a program in the background, once or on a calendar, and logs each run. run PL/SQL in the background on a calendar, and scheduler jobs log each run in USER_SCHEDULER_JOB_RUN_DETAILS. A lock-free reservation lets many sessions change one busy number, such as the stock of a best seller, without waiting for each other’s row locks.

Checkpoint

Check: Waiting, NOWAIT, WAIT n and SKIP LOCKED

  1. Question 1 of 2 What does SELECT ... FOR UPDATE NOWAIT do when one of its rows is locked by another transaction?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: Fails at once with ORA-00054

    NOWAIT turns a wait into an immediate ORA-00054, so the caller can say at once that the row is busy.

  2. Question 2 of 2 Session A holds jobs 2 and 5 with FOR UPDATE. Session B selects all six new jobs FOR UPDATE SKIP LOCKED. What does B get?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: Jobs 1, 3, 4 and 6, locked by B

    SKIP LOCKED is made for queues: each consumer takes the rows nobody holds without waiting for the others.

A job queue that several workers share with SKIP LOCKED Pro: opens with a Pro, Premium or Ultimate pass

A queue table needs two promises: no job is taken by two workers, and no job is lost when a worker dies. Below, the claim is built to keep both, and a run of three workers, one of which crashes, is replayed step by step.

In this part:

  • Claiming one job at a time, step by step
  • A worker that crashes, and a job that always fails

3 runnable examples (Python, SQL) · about 4 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Lost updates reproduced, and the checks that prevent them Pro: opens with a Pro, Premium or Ultimate pass

A lost update leaves no error behind: two sessions both succeed, and one of the changes is gone. Below, one is reproduced with real amounts, and three ways to prevent it are compared by how long the read stays open.

In this part:

  • Two writes from one old read lose a withdrawal
  • Choosing among the three checks for your own case
  • Where a version check stops protecting a row

3 runnable examples (Python, SQL) · about 4 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Scheduler jobs that keep the queue running, and lock-free reservations Pro: opens with a Pro, Premium or Ultimate pass

The sweep of the queue must run every few minutes whether or not anyone is watching. Below it becomes a scheduler job whose calendar is checked before it is enabled, followed by a way for many sessions to change one hot number without waiting for each other’s locks.

In this part:

  • A job that runs on a calendar, checked before it is enabled
  • Lock-free reservations for a hot number such as stock

3 runnable examples (Python, SQL) · about 5 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Practise: reads, waits and skips

Each question describes two sessions and one row. Say who waits, who fails and what each one reads:

Practice that adapts to you

Practise this lesson

6 questions about 6 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 6 Which statement never waits for another session's row locks?

    Choose one answer.

    Show the answer: Question 1 of 6

    Answer: A plain SELECT

    Waiting belongs to locks; a plain query asks for none.

  2. Question 2 of 6 Session A has set job 1's amount from 100 to 999 without committing. Where does session B's query get the value 100?

    Choose one answer.

    Show the answer: Question 2 of 6

    Answer: From undo data, which holds the version before A's change

    Oracle achieves read consistency through undo data, as its Concepts guide says.

  3. Question 3 of 6 A report sums every balance in one query that runs for 40 seconds while transfers commit. What does the sum reflect?

    Choose one answer.

    Show the answer: Question 3 of 6

    Answer: The balances as committed at one point in time, when the query began

    Every query sees one committed state, so a long report adds up consistently even while writers commit.

  4. Question 4 of 6 What does SELECT ... FOR UPDATE with no wait clause do when a row is locked?

    Choose one answer.

    Show the answer: Question 4 of 6

    Answer: Waits until the other transaction commits or rolls back

    Without NOWAIT, WAIT n or SKIP LOCKED, the database waits until the row is available.

  5. Question 5 of 6 A SELECT ... FOR UPDATE WAIT 3 meets a row that stays locked for another 10 seconds. After how many seconds does it fail?

    Type a number.

    Show the answer: Question 5 of 6

    Answer: 3

    WAIT 3 waits up to 3 seconds, and the row is still locked then, so the statement fails after 3 seconds.

  6. Question 6 of 6 An edit screen locks a customer row when a clerk opens it. When a second clerk opens the same customer, the screen should say at once that someone else is editing. Which clause fits?

    Choose one answer.

    Show the answer: Question 6 of 6

    Answer: NOWAIT

    Choose by what the caller needs: an immediate answer (NOWAIT), a short pause (WAIT n), or other work (SKIP LOCKED).

Interview questions

Warm-up (fresher to 2–5 years): what is the practical difference between NOWAIT and WAIT n on a locked row?

Both stop a SELECT … FOR UPDATE from waiting without limit for another transaction’s row lock. NOWAIT fails at once with ORA-00054, which suits a screen that should say “someone else is editing this” straight away. WAIT n waits up to n seconds, then fails if the row is still locked, which suits a short job that can afford a pause. Without either clause the session waits until the holder commits or rolls back.

Three longer questions follow: a payment sent twice from a queue, seats sold beyond capacity, and a nightly job that stopped without anyone noticing:

  1. Mid to senior

    Four workers serve a payment queue table. Each selects the oldest job with status 'new' and then, in a second statement, updates it to 'running'. Twice last week one payment was sent two times. Explain the race, and rework the claim so that a job can never be taken twice.

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  2. Mid to senior

    A booking procedure reads seats_left into a variable, checks that it covers the request, and later sets seats_left to the variable minus the seats booked. In a busy sale, 212 seats were sold for an event of 200, and no error appeared. Explain why, and give two fixes.

    Model answer, Pro. First step and follow-ups

  3. Senior to staff

    A nightly DBMS_SCHEDULER job settles the day's card payments. Finance found that it had not run for nine nights, and no alert fired. Where do you look first, what could have stopped it, and how do you make a silent stop impossible to miss?

    Model answer, Pro. First step and follow-ups

Flashcards · 8 cards

Recall it, then check

Say the answer to yourself before you look: recalling it is what makes it stick.

  1. Does a reader in Oracle ever wait for a writer?

    No. While a row is being changed the database uses undo data to give each query the version last committed, and every query gets its rows from one committed point in time. Waiting belongs to locks, never to reading.

  2. When is a row locked, and how long does the lock last?

    Only when a writer changes it or when SELECT ... FOR UPDATE asks for its lock, and the lock lasts until the transaction commits or rolls back. A writer blocks another writer of the same row.

  3. Where may SELECT ... FOR UPDATE not be used?

    Only in a top-level query: not with DISTINCT, set operators, GROUP BY or aggregate functions.

  4. What do the four lock-wait choices do when a selected row is held by another transaction?

    With no clause the session waits until that transaction ends; NOWAIT fails at once with ORA-00054; WAIT 2 waits up to two seconds and then fails if the row is still locked; SKIP LOCKED leaves that row out and locks and returns the others.

  5. What unit does WAIT count in?

    Seconds, unless MILLISECONDS or MICROSECONDS follows the number.

  6. What is SKIP LOCKED built for, and what does it return when every job is held?

    Multiconsumer queues: each consumer skips the rows other consumers hold and gets the remaining rows without waiting. When every row is locked it returns no row at once, which a worker reads as nothing to do now.

  7. What is a lost update, and what stops it?

    A change that another session overwrites from an older read. An optimistic check in the UPDATE, which refuses to write when the row has changed since it was read, stops it.

  8. What runs PL/SQL in the background, and where is each run recorded?

    Scheduler jobs, which run on a calendar, and each run is logged in USER_SCHEDULER_JOB_RUN_DETAILS.

Key takeaways

  • In Oracle a reader never waits for a writer: a query reads the last committed version of each row, from undo data.
  • A row is locked only by a writer or by SELECT … FOR UPDATE, and the lock lasts until the transaction ends.
  • With no clause FOR UPDATE waits, NOWAIT fails at once, WAIT n waits n seconds, and SKIP LOCKED leaves locked rows out.
  • SKIP LOCKED queues and optimistic checks put row locks to work for shared queues and concurrent edits, and scheduler jobs run such work in the background.

Terms in this lesson

lost update
A change that disappears because another session, starting from an older read of the same row, writes over it. Both statements succeed, and no error is raised.
optimistic locking
A way to prevent lost updates that holds no lock between reading a row and writing it: the write itself checks that the row has not changed since it was read.
read consistency
The guarantee that a query sees data as committed at one point in time. While a row is being changed, Oracle builds its last committed version from undo data, so readers never wait for writers.
scheduler job
A job of Oracle Scheduler, created with DBMS_SCHEDULER.CREATE_JOB, that runs PL/SQL or a program in the background, once or on a calendar, and logs each run.
SKIP LOCKED
A clause of SELECT ... FOR UPDATE that leaves out the rows another transaction has locked and locks and returns the others, so several consumers of a queue can work without waiting for each other.

References

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.