locked
Dirty reads vs phantom reads RRS feed

  • Question

  • Hi,

    What is the difference between a "Dirty Read" and "Phantom Reads". Can anyone explain in brief or give an example?

    Thanks in advance.
    Saturday, September 27, 2014 11:26 AM

Answers

  • Please have a look at this link: 

    Transaction Isolation Levels


    Saeid Hasani [sqldevelop]

    Saturday, September 27, 2014 11:30 AM
  • A dirty read is an uncommitted read, which may or may not be exist in the table. A phantom is a ghost record that doesn't appear in a transaction initially but appears if it is read again because some other transaction has inserted rows matching the criteria. Here are examples of both:

    --Dirty read example
    create table t1 (c1 int null, c2 varchar(50) null)
    go
    
    --
    insert t1(c1, c2) values (1, 'one')
    insert t1(c1, c2) values (2, 'two')
    insert t1(c1, c2) values (3, 'three')
    insert t1(c1, c2) values (4, 'four')
    
    begin tran
    update t1 set c2 = 'zero'
    
    -- let this run in the current query window and open a new query window to run the below statement 
    --and you will see all 4 rows having a value of 0 in column c2, which is uncommitted data
    select * from t1 with (nolock) 
    
    --uncomment this and run the below statement and rerun the  above statement 
    --and you will see the previous values of one, two, three and four
    --rollback tran
    

    Here's an example of a phantom reads: 

    --Phantom example
    create table t1 (c1 int null, c2 varchar(50) null)
    go
    
    --
    insert t1(c1, c2) values (1, 'one')
    insert t1(c1, c2) values (2, 'two')
    insert t1(c1, c2) values (3, 'three')
    insert t1(c1, c2) values (4, 'four')
    
    
    -- let this run in the current first query window and open a second query window to run the below statement 
    --and you will see all 2 rows having a value in column c2 starting with character t
    begin tran
    select * from t1 
    where c2 like 't%'
    
    --now insert the new value of ten (matching the query criteria - starts with t) from the first query window
    insert t1(c1, c2) values (10, 'ten')
    
    --Run the below statement again from the second query window that is open and you will see the new row 
    --that got inserted - so 3 rows are seen including the newly inserted ten
    --this new row is a phantom read
    select * from t1 
    where c2 like 't%'
    
    --uncomment this and run the below statement in the second query window
    --rollback tran
    


    Satish Kartan www.sqlfood.com

    Saturday, September 27, 2014 10:56 PM

All replies

  • Please have a look at this link: 

    Transaction Isolation Levels


    Saeid Hasani [sqldevelop]

    Saturday, September 27, 2014 11:30 AM
  • A dirty read is an uncommitted read, which may or may not be exist in the table. A phantom is a ghost record that doesn't appear in a transaction initially but appears if it is read again because some other transaction has inserted rows matching the criteria. Here are examples of both:

    --Dirty read example
    create table t1 (c1 int null, c2 varchar(50) null)
    go
    
    --
    insert t1(c1, c2) values (1, 'one')
    insert t1(c1, c2) values (2, 'two')
    insert t1(c1, c2) values (3, 'three')
    insert t1(c1, c2) values (4, 'four')
    
    begin tran
    update t1 set c2 = 'zero'
    
    -- let this run in the current query window and open a new query window to run the below statement 
    --and you will see all 4 rows having a value of 0 in column c2, which is uncommitted data
    select * from t1 with (nolock) 
    
    --uncomment this and run the below statement and rerun the  above statement 
    --and you will see the previous values of one, two, three and four
    --rollback tran
    

    Here's an example of a phantom reads: 

    --Phantom example
    create table t1 (c1 int null, c2 varchar(50) null)
    go
    
    --
    insert t1(c1, c2) values (1, 'one')
    insert t1(c1, c2) values (2, 'two')
    insert t1(c1, c2) values (3, 'three')
    insert t1(c1, c2) values (4, 'four')
    
    
    -- let this run in the current first query window and open a second query window to run the below statement 
    --and you will see all 2 rows having a value in column c2 starting with character t
    begin tran
    select * from t1 
    where c2 like 't%'
    
    --now insert the new value of ten (matching the query criteria - starts with t) from the first query window
    insert t1(c1, c2) values (10, 'ten')
    
    --Run the below statement again from the second query window that is open and you will see the new row 
    --that got inserted - so 3 rows are seen including the newly inserted ten
    --this new row is a phantom read
    select * from t1 
    where c2 like 't%'
    
    --uncomment this and run the below statement in the second query window
    --rollback tran
    


    Satish Kartan www.sqlfood.com

    Saturday, September 27, 2014 10:56 PM