{"id":5447,"date":"2026-02-15T16:53:58","date_gmt":"2026-02-15T11:23:58","guid":{"rendered":"https:\/\/w3buddy.com\/?p=5447"},"modified":"2026-02-15T16:53:59","modified_gmt":"2026-02-15T11:23:59","slug":"oracle-transaction-management-read-consistency","status":"publish","type":"post","link":"https:\/\/w3buddy.com\/blog\/oracle-transaction-management-read-consistency\/","title":{"rendered":"Oracle Transaction Management &#038; Read Consistency"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Oracle&#8217;s transaction management and read consistency mechanisms are fundamental to maintaining data integrity in multi-user environments. Understanding how Oracle handles concurrent transactions, prevents dirty reads, and ensures data consistency is crucial for database administrators and developers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this guide, we&#8217;ll explore Oracle&#8217;s ACID properties, multi-version concurrency control (MVCC), and read consistency implementation.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is a Transaction?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A transaction is a logical unit of work containing one or more SQL statements that must succeed or fail as a single unit.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502         TRANSACTION EXAMPLE            \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502                                        \u2502\n\u2502  BEGIN TRANSACTION (implicit)          \u2502\n\u2502    \u2193                                   \u2502\n\u2502  UPDATE accounts                       \u2502\n\u2502  SET balance = balance - 1000          \u2502\n\u2502  WHERE account_id = 101;               \u2502\n\u2502    \u2193                                   \u2502\n\u2502  UPDATE accounts                       \u2502\n\u2502  SET balance = balance + 1000          \u2502\n\u2502  WHERE account_id = 102;               \u2502\n\u2502    \u2193                                   \u2502\n\u2502  COMMIT or ROLLBACK                    \u2502\n\u2502                                        \u2502\n\u2502  All or Nothing!                       \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">ACID Properties in Oracle<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Oracle guarantees ACID properties for every transaction.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. Atomicity (All or Nothing)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Money transfer example\nBEGIN\n    UPDATE accounts SET balance = balance - 1000 WHERE account_id = 101;\n    UPDATE accounts SET balance = balance + 1000 WHERE account_id = 102;\n    COMMIT;  -- Both updates succeed\nEXCEPTION\n    WHEN OTHERS THEN\n        ROLLBACK;  -- Both updates fail\n        -- Account 101 is NOT debited if account 102 credit fails\nEND;\n\/<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>How Oracle Ensures Atomicity:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Undo segments store before images<\/li>\n\n\n\n<li>ROLLBACK restores original state<\/li>\n\n\n\n<li>No partial transactions visible<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2. Consistency (Valid State to Valid State)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Constraint ensures consistency\nCREATE TABLE accounts (\n    account_id NUMBER PRIMARY KEY,\n    balance NUMBER CHECK (balance &gt;= 0)  -- Business rule\n);\n\n-- This will fail and rollback\nUPDATE accounts SET balance = -500 WHERE account_id = 101;\n-- ORA-02290: check constraint violated\n-- Database remains consistent (no negative balances)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>How Oracle Ensures Consistency:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Constraint validation<\/li>\n\n\n\n<li>Trigger execution<\/li>\n\n\n\n<li>Referential integrity checks<\/li>\n\n\n\n<li>Automatic rollback on violation<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">3. Isolation (Transactions Don&#8217;t Interfere)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Session 1\nUPDATE employees SET salary = 60000 WHERE employee_id = 101;\n-- Not committed\n\n-- Session 2\nSELECT salary FROM employees WHERE employee_id = 101;\n-- Result: 50000 (old value)\n-- Session 2 doesn't see Session 1's uncommitted change\n\n-- Session 1\nCOMMIT;\n\n-- Session 2\nSELECT salary FROM employees WHERE employee_id = 101;\n-- Result: 60000 (now sees committed change)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>How Oracle Ensures Isolation:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Row-level locking<\/li>\n\n\n\n<li>Read consistency via undo<\/li>\n\n\n\n<li>Multi-version concurrency control (MVCC)<\/li>\n\n\n\n<li>No dirty reads<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">4. Durability (Permanent After COMMIT)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Transaction commits\nINSERT INTO orders VALUES (1001, SYSDATE, 'Customer A');\nCOMMIT;\n-- \"Commit complete\"\n\n-- Database crashes 1 second later\n-- Power failure, system crash, etc.\n\n-- After restart: Order 1001 still exists\n-- Redo logs ensure durability<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>How Oracle Ensures Durability:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Redo logs written before COMMIT returns<\/li>\n\n\n\n<li>Write-ahead logging (WAL)<\/li>\n\n\n\n<li>Crash recovery replays redo<\/li>\n\n\n\n<li>Changes permanent once committed<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Transaction Control Statements<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Transaction Control<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Start transaction (implicit with first DML)\nINSERT INTO employees VALUES (101, 'John', 50000);\n\n-- Set transaction properties\nSET TRANSACTION READ ONLY;\nSET TRANSACTION READ WRITE;\nSET TRANSACTION ISOLATION LEVEL SERIALIZABLE;\nSET TRANSACTION NAME 'Monthly_Payroll';\n\n-- Create savepoint\nSAVEPOINT before_update;\n\n-- Partial rollback\nROLLBACK TO SAVEPOINT before_update;\n\n-- Complete transaction\nCOMMIT;  -- or ROLLBACK;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Transaction Naming<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Name transaction for monitoring\nSET TRANSACTION NAME 'order_processing_batch';\n\nINSERT INTO orders VALUES (1001, SYSDATE);\nINSERT INTO order_items VALUES (1, 1001, 'Product', 10);\nCOMMIT;\n\n-- View named transactions\nSELECT name, start_time, used_ublk\nFROM v$transaction;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Read-Only Transactions<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Ensure no modifications\nSET TRANSACTION READ ONLY;\n\n-- These work\nSELECT * FROM employees;\nSELECT COUNT(*) FROM orders;\n\n-- These fail\nUPDATE employees SET salary = 60000;\n-- ORA-01456: may not perform insert\/delete\/update operation inside a read-only transaction\n\nCOMMIT;  -- End read-only transaction<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Oracle&#8217;s Read Consistency Model<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Oracle uses <strong>Statement-Level Read Consistency<\/strong> by default.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Statement-Level Read Consistency<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Long-running query starts at 10:00:00 AM\nSELECT * FROM large_table WHERE status = 'ACTIVE';\n-- Query takes 5 minutes\n\n-- At 10:02:00 AM, another session:\nUPDATE large_table SET status = 'INACTIVE' WHERE id = 12345;\nCOMMIT;\n\n-- Original query completes at 10:05:00 AM\n-- Results show data as of 10:00:00 AM (query start time)\n-- Row 12345 still shows 'ACTIVE' in query results\n-- No dirty reads, phantom reads, or non-repeatable reads<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>How It Works:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Query Start (SCN: 1234567):\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502  Oracle records query start SCN        \u2502\n\u2502  Reads data blocks from buffer cache   \u2502\n\u2502  If block changed after SCN 1234567:   \u2502\n\u2502    \u2192 Reads undo to reconstruct         \u2502\n\u2502    \u2192 Returns data as of SCN 1234567    \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\nResult:\n- Consistent view of data\n- No blocking of other transactions\n- No locks on read data<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Transaction-Level Read Consistency<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Set transaction isolation level\nSET TRANSACTION ISOLATION LEVEL SERIALIZABLE;\n\n-- Query 1 at 10:00:00 (SCN: 1234567)\nSELECT COUNT(*) FROM orders WHERE status = 'PENDING';\n-- Result: 100 orders\n\n-- Another session at 10:01:00:\nINSERT INTO orders VALUES (1001, SYSDATE, 'PENDING');\nCOMMIT;\n\n-- Query 2 at 10:02:00 (same transaction)\nSELECT COUNT(*) FROM orders WHERE status = 'PENDING';\n-- Result: 100 orders (still!)\n-- Sees data as of transaction start (SCN: 1234567)\n\nCOMMIT;  -- End transaction\n\n-- New query\nSELECT COUNT(*) FROM orders WHERE status = 'PENDING';\n-- Result: 101 orders (now sees new insert)<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Multi-Version Concurrency Control (MVCC)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Oracle&#8217;s MVCC allows readers and writers to work without blocking each other.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">How MVCC Works<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Current Data Block (Buffer Cache):\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502  Block SCN: 1234570                    \u2502\n\u2502  Row 1: EmpID=101, Salary=60000       \u2502\n\u2502  (Modified by Session 1, not committed)\u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\nUndo Segment:\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502  SCN: 1234567                          \u2502\n\u2502  Row 1: EmpID=101, Salary=50000        \u2502\n\u2502  (Before image)                        \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\nSession 2 Query (started at SCN 1234568):\n1. Reads current block (SCN: 1234570)\n2. Detects SCN is too new\n3. Reads undo segment\n4. Reconstructs row as of SCN 1234568\n5. Returns: Salary=50000\n\nBenefits:\n\u2713 Readers don't block writers\n\u2713 Writers don't block readers\n\u2713 No dirty reads\n\u2713 Consistent results<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">MVCC Example<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Session 1: Update but don't commit\nUPDATE employees SET salary = 70000 WHERE employee_id = 101;\n-- Row locked, change in buffer cache\n\n-- Session 2: Read same row\nSELECT salary FROM employees WHERE employee_id = 101;\n-- Result: 60000 (old value from undo)\n-- NO WAITING, returns immediately\n\n-- Session 3: Try to update same row\nUPDATE employees SET department_id = 20 WHERE employee_id = 101;\n-- WAITS (row is locked)\n\n-- Session 1: Commit\nCOMMIT;\n\n-- Session 2: Read again\nSELECT salary FROM employees WHERE employee_id = 101;\n-- Result: 70000 (new value, now committed)\n\n-- Session 3: Now proceeds\n-- UPDATE completes<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">SCN (System Change Number)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">SCN is Oracle&#8217;s logical clock for ordering transactions.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Understanding SCN<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Get current SCN\nSELECT CURRENT_SCN FROM V$DATABASE;\n-- Result: 1234567\n\n-- Perform transaction\nUPDATE employees SET salary = 60000;\nCOMMIT;  -- Assigned SCN: 1234568\n\n-- Query as of specific SCN\nSELECT salary \nFROM employees AS OF SCN 1234567\nWHERE employee_id = 101;\n-- Result: 50000 (before update)\n\nSELECT salary \nFROM employees AS OF SCN 1234568\nWHERE employee_id = 101;\n-- Result: 60000 (after update)<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">SCN in Action<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Timestamp to SCN\nSELECT TIMESTAMP_TO_SCN(SYSDATE - 1) FROM DUAL;\n-- Returns SCN from 24 hours ago\n\n-- SCN to Timestamp\nSELECT SCN_TO_TIMESTAMP(1234567) FROM DUAL;\n-- Returns time when SCN was generated\n\n-- Query historical data\nSELECT * FROM employees\nAS OF TIMESTAMP (SYSDATE - 1\/24)  -- 1 hour ago\nWHERE department_id = 10;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Isolation Levels in Oracle<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Oracle supports two isolation levels.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. READ COMMITTED (Default)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Default isolation level\n-- Each query sees committed data as of query start\n\n-- Session 1\nUPDATE employees SET salary = 60000 WHERE employee_id = 101;\n-- Not committed\n\n-- Session 2\nSELECT salary FROM employees WHERE employee_id = 101;\n-- Result: 50000 (doesn't see uncommitted change)\n\n-- Session 1\nCOMMIT;\n\n-- Session 2 (new query)\nSELECT salary FROM employees WHERE employee_id = 101;\n-- Result: 60000 (sees newly committed change)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Characteristics:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Statement-level read consistency<\/li>\n\n\n\n<li>Sees changes committed by other transactions<\/li>\n\n\n\n<li>No dirty reads<\/li>\n\n\n\n<li>Possible non-repeatable reads within transaction<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2. SERIALIZABLE<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Transaction-level read consistency\nSET TRANSACTION ISOLATION LEVEL SERIALIZABLE;\n\n-- All queries see data as of transaction start\nSELECT COUNT(*) FROM orders;\n-- Result: 100\n\n-- Another session inserts and commits\n-- INSERT INTO orders...\n-- COMMIT;\n\n-- This transaction still sees old count\nSELECT COUNT(*) FROM orders;\n-- Result: 100 (unchanged within transaction)\n\nCOMMIT;\n\n-- New transaction sees updated count\nSELECT COUNT(*) FROM orders;\n-- Result: 101<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Characteristics:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Transaction-level read consistency<\/li>\n\n\n\n<li>Phantom reads prevented<\/li>\n\n\n\n<li>May get serialization errors<\/li>\n\n\n\n<li>Higher overhead<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Comparison<\/h3>\n\n\n\n<figure class=\"wp-block-table has-small-font-size\"><table><thead><tr><th>Aspect<\/th><th>READ COMMITTED<\/th><th>SERIALIZABLE<\/th><\/tr><\/thead><tbody><tr><td><strong>Consistency<\/strong><\/td><td>Statement-level<\/td><td>Transaction-level<\/td><\/tr><tr><td><strong>Performance<\/strong><\/td><td>Better<\/td><td>Lower<\/td><\/tr><tr><td><strong>Phantom Reads<\/strong><\/td><td>Possible<\/td><td>Prevented<\/td><\/tr><tr><td><strong>Use Case<\/strong><\/td><td>OLTP systems<\/td><td>Reports, batch jobs<\/td><\/tr><tr><td><strong>Default<\/strong><\/td><td>Yes<\/td><td>No<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Locking Mechanisms<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Row-Level Locking<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Automatic row locking on DML\nUPDATE employees SET salary = 60000 WHERE employee_id = 101;\n-- Only row 101 is locked\n\n-- Other sessions can modify other rows\nUPDATE employees SET salary = 55000 WHERE employee_id = 102;\n-- No waiting, different row<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Manual Locking<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- SELECT FOR UPDATE (explicit lock)\nSELECT * FROM employees \nWHERE employee_id = 101\nFOR UPDATE;\n-- Row locked until COMMIT or ROLLBACK\n\n-- Other session tries to update\nUPDATE employees SET salary = 60000 WHERE employee_id = 101;\n-- WAITS until first session commits\n\n-- Lock with NOWAIT (fail immediately if locked)\nSELECT * FROM employees \nWHERE employee_id = 101\nFOR UPDATE NOWAIT;\n-- ORA-00054: resource busy and acquire with NOWAIT specified\n\n-- Lock with timeout\nSELECT * FROM employees \nWHERE employee_id = 101\nFOR UPDATE WAIT 5;\n-- Waits max 5 seconds, then fails<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Lock Types<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Table-level lock (rare)\nLOCK TABLE employees IN EXCLUSIVE MODE;\n-- Entire table locked\n\n-- Row share lock (for foreign key checks)\nLOCK TABLE employees IN ROW SHARE MODE;\n\n-- Share lock (allow reads, prevent writes)\nLOCK TABLE employees IN SHARE MODE;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Deadlock Detection<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Oracle automatically detects and resolves deadlocks.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Session 1\nUPDATE accounts SET balance = 1000 WHERE account_id = 101;\n\n-- Session 2\nUPDATE accounts SET balance = 2000 WHERE account_id = 102;\n\n-- Session 1 (tries to lock Session 2's row)\nUPDATE accounts SET balance = 3000 WHERE account_id = 102;\n-- WAITS\n\n-- Session 2 (tries to lock Session 1's row)\nUPDATE accounts SET balance = 4000 WHERE account_id = 101;\n-- DEADLOCK DETECTED!\n-- ORA-00060: deadlock detected while waiting for resource\n-- Session 2's statement is rolled back automatically\n\n-- Session 1 now proceeds\n-- UPDATE completes<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Deadlock Resolution:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Oracle detects deadlock immediately<\/li>\n\n\n\n<li>Chooses victim (least work to rollback)<\/li>\n\n\n\n<li>Victim&#8217;s statement rolled back<\/li>\n\n\n\n<li>Other session proceeds<\/li>\n\n\n\n<li>Application should retry<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Undo and Redo in Transaction Management<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Undo Segment Usage<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- View undo usage\nSELECT s.username,\n       s.sid,\n       t.used_ublk * 8192\/1024\/1024 undo_mb,\n       t.start_time\nFROM v$transaction t\nJOIN v$session s ON t.ses_addr = s.saddr\nORDER BY undo_mb DESC;\n\n-- Check undo retention\nSHOW PARAMETER undo_retention;\n\n-- View undo tablespace\nSELECT tablespace_name,\n       status,\n       COUNT(*) extents,\n       SUM(bytes)\/1024\/1024 size_mb\nFROM dba_undo_extents\nGROUP BY tablespace_name, status;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Redo Log Usage<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- View redo generation\nSELECT name, value\nFROM v$sysstat\nWHERE name IN ('redo size', 'redo writes', 'user commits');\n\n-- Check current redo log\nSELECT group#, \n       sequence#,\n       bytes\/1024\/1024 size_mb,\n       status\nFROM v$log\nWHERE status = 'CURRENT';\n\n-- View redo log switch frequency\nSELECT TO_CHAR(first_time, 'YYYY-MM-DD HH24') hour,\n       COUNT(*) switches\nFROM v$log_history\nWHERE first_time &gt; SYSDATE - 1\nGROUP BY TO_CHAR(first_time, 'YYYY-MM-DD HH24')\nORDER BY hour;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Flashback Query (Point-in-Time Queries)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Oracle&#8217;s read consistency extends to querying historical data.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Flashback Query Syntax<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Query as of timestamp\nSELECT * FROM employees\nAS OF TIMESTAMP (SYSDATE - 1\/24)  -- 1 hour ago\nWHERE department_id = 10;\n\n-- Query as of SCN\nSELECT * FROM employees\nAS OF SCN 1234567\nWHERE department_id = 10;\n\n-- View changes between two points\nSELECT * FROM employees\nVERSIONS BETWEEN TIMESTAMP \n    (SYSDATE - 1\/24) AND SYSDATE\nWHERE employee_id = 101;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Flashback Example<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Current data\nSELECT salary FROM employees WHERE employee_id = 101;\n-- Result: 70000\n\n-- Update and commit\nUPDATE employees SET salary = 80000 WHERE employee_id = 101;\nCOMMIT;\n\n-- View current\nSELECT salary FROM employees WHERE employee_id = 101;\n-- Result: 80000\n\n-- View 5 minutes ago\nSELECT salary FROM employees\nAS OF TIMESTAMP (SYSDATE - 5\/1440)\nWHERE employee_id = 101;\n-- Result: 70000 (old value)\n\n-- View all versions in last hour\nSELECT versions_starttime,\n       versions_endtime,\n       versions_operation,\n       salary\nFROM employees\nVERSIONS BETWEEN TIMESTAMP \n    (SYSDATE - 1\/24) AND SYSDATE\nWHERE employee_id = 101;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Best Practices<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. Keep Transactions Short<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Bad: Long transaction\nBEGIN\n    FOR emp IN (SELECT * FROM employees) LOOP\n        -- Complex processing\n        DBMS_LOCK.SLEEP(1);  -- Simulating long work\n        UPDATE employees SET processed = 'Y' WHERE employee_id = emp.employee_id;\n    END LOOP;\n    COMMIT;  -- Hours later!\nEND;\n\n-- Good: Batch commits\nBEGIN\n    FOR emp IN (SELECT * FROM employees) LOOP\n        UPDATE employees SET processed = 'Y' WHERE employee_id = emp.employee_id;\n        IF MOD(SQL%ROWCOUNT, 1000) = 0 THEN\n            COMMIT;  -- Commit every 1000 rows\n        END IF;\n    END LOOP;\n    COMMIT;\nEND;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2. Use Appropriate Isolation Level<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- OLTP: Use default READ COMMITTED\n-- Fast, low overhead\n\n-- Reports: Use SERIALIZABLE for consistency\nSET TRANSACTION ISOLATION LEVEL SERIALIZABLE;\n-- Financial reports\n-- Audit reports\n-- Data exports<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">3. Handle Deadlocks<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Retry logic for deadlocks\nDECLARE\n    v_attempts NUMBER := 0;\n    v_max_attempts CONSTANT NUMBER := 3;\n    deadlock_detected EXCEPTION;\n    PRAGMA EXCEPTION_INIT(deadlock_detected, -60);\nBEGIN\n    LOOP\n        BEGIN\n            -- Transaction logic\n            UPDATE accounts SET balance = balance - 1000 WHERE account_id = 101;\n            UPDATE accounts SET balance = balance + 1000 WHERE account_id = 102;\n            COMMIT;\n            EXIT;  -- Success\n        EXCEPTION\n            WHEN deadlock_detected THEN\n                v_attempts := v_attempts + 1;\n                IF v_attempts &gt;= v_max_attempts THEN\n                    RAISE;\n                END IF;\n                DBMS_LOCK.SLEEP(1);  -- Wait before retry\n        END;\n    END LOOP;\nEND;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">4. Monitor Transaction Activity<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Active transactions\nSELECT s.username,\n       s.sid,\n       s.serial#,\n       t.start_time,\n       t.used_ublk,\n       sq.sql_text\nFROM v$transaction t\nJOIN v$session s ON t.ses_addr = s.saddr\nLEFT JOIN v$sql sq ON s.sql_id = sq.sql_id\nORDER BY t.start_time;\n\n-- Long-running transactions\nSELECT s.username,\n       s.sid,\n       ROUND((SYSDATE - t.start_date) * 24 * 60) duration_min,\n       t.used_ublk\nFROM v$transaction t\nJOIN v$session s ON t.ses_addr = s.saddr\nWHERE (SYSDATE - t.start_date) * 24 * 60 &gt; 10  -- &gt; 10 minutes\nORDER BY duration_min DESC;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Monitoring Queries<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Transaction statistics\nSELECT name, value\nFROM v$sysstat\nWHERE name IN (\n    'user commits',\n    'user rollbacks',\n    'transaction rollbacks',\n    'active txn count during cleanout'\n);\n\n-- Lock waits\nSELECT event,\n       total_waits,\n       time_waited\/100 time_waited_sec,\n       average_wait\/100 avg_wait_sec\nFROM v$system_event\nWHERE event LIKE '%enq%'\n   OR event LIKE '%lock%'\nORDER BY time_waited DESC;\n\n-- Undo generation rate\nSELECT (value\/1024\/1024) undo_mb_per_sec\nFROM v$sysstat\nWHERE name = 'undo change vector size';\n\n-- Read consistency statistics\nSELECT name, value\nFROM v$sysstat\nWHERE name LIKE '%consistent%'\n   OR name LIKE '%CR%';<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Oracle&#8217;s transaction management and read consistency model provides robust data integrity while maintaining high concurrency. The combination of ACID properties, MVCC, and statement-level read consistency ensures reliable operations in multi-user environments.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Key Takeaways:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>ACID properties<\/strong> &#8211; Guaranteed for all transactions<\/li>\n\n\n\n<li><strong>MVCC<\/strong> &#8211; Readers don&#8217;t block writers, writers don&#8217;t block readers<\/li>\n\n\n\n<li><strong>SCN-based consistency<\/strong> &#8211; Ensures consistent reads<\/li>\n\n\n\n<li><strong>No dirty reads<\/strong> &#8211; Always see committed data<\/li>\n\n\n\n<li><strong>Statement-level consistency<\/strong> &#8211; Default, best for OLTP<\/li>\n\n\n\n<li><strong>Serializable isolation<\/strong> &#8211; Transaction-level consistency for reports<\/li>\n\n\n\n<li><strong>Undo enables consistency<\/strong> &#8211; Critical for read consistency<\/li>\n\n\n\n<li><strong>Automatic deadlock detection<\/strong> &#8211; Oracle handles conflicts<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Understanding these concepts is essential for:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Designing concurrent applications<\/li>\n\n\n\n<li>Troubleshooting locking issues<\/li>\n\n\n\n<li>Optimizing transaction performance<\/li>\n\n\n\n<li>Ensuring data integrity<\/li>\n\n\n\n<li>DBA interviews and certifications<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Remember:<\/strong> Oracle&#8217;s architecture allows thousands of concurrent users to read and modify data safely without compromising consistency or performance!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Oracle&#8217;s transaction management and read consistency mechanisms are fundamental to maintaining data integrity in multi-user environments. Understanding how Oracle handles concurrent transactions, prevents dirty reads, and ensures data consistency is crucial for database administrators and developers. In this guide, we&#8217;ll explore Oracle&#8217;s ACID properties, multi-version concurrency control (MVCC), and read consistency implementation. What is a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":5449,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"googlesitekit_rrm_CAowu461DA:productID":"","footnotes":""},"categories":[1225],"tags":[],"class_list":["post-5447","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-database"],"_links":{"self":[{"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/posts\/5447","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/comments?post=5447"}],"version-history":[{"count":1,"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/posts\/5447\/revisions"}],"predecessor-version":[{"id":5448,"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/posts\/5447\/revisions\/5448"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/media\/5449"}],"wp:attachment":[{"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/media?parent=5447"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/categories?post=5447"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/tags?post=5447"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}