About Me

My photo
Mumbai, Maharastra, India
He has more than 7.6 years of experience in the software development. He has spent most of the times in web/desktop application development. He has sound knowledge in various database concepts. You can reach him at viki.keshari@gmail.com https://www.linkedin.com/in/vikrammahapatra/ https://twitter.com/VikramMahapatra http://www.facebook.com/viki.keshari

Search This Blog

Showing posts with label Isolation. Show all posts
Showing posts with label Isolation. Show all posts

Saturday, September 7, 2019

What is Repeatable Read problem and how to solve it?

Let’s replicate the problem, for which I am creating a table StudentMarks and insert three records
create table studentMarks (
       id int
       ,name varchar(50)
       ,total_marks int
       )
    insert into studentMarks(id,name,total_marks) values( 1,'Prayansh',430);
    insert into studentMarks(id,name,total_marks) values( 2,'Rishika',345);
    insert into studentMarks(id,name,total_marks) values( 3,'Aayansh',390);         

Now lets open a transaction in a new session and try to read this table twice, and in between two read keep a delay of 18 Sec

Open Session1, and execute below transaction
    begin tran
    select * from studentMarks where ID in(1,2)
    waitfor delay '00:00:18'
    select * from studentMarks where ID in (1,2)
    rollback

Parallely open another session and execute below session
update studentMarks
set    total_marks=499 where id=1

Now the output from the first session you will find
 id          name         total_marks
----------- ----------------------
1           Prayansh      430
2           Rishika       345

(2 row(s) affected)

id          name          total_marks
----------- -------------------------
1           Prayansh      499
2           Rishika       345

(2 row(s) affected)

Here if you look at session1 output, a same select statement gives two different outputs, that is because , while session one is waiting for 18 second, session two updated the marks of id=1 to 499.

This is a problem with repeatable read if any outside transaction updates the data in between two reads.

How to avoid it
It can be avoided by setting transaction isolation level to repeatable read, let’s see how

set transaction isolation level repeatable read
    begin tran
    select * from studentMarks where ID in(1,2)
    waitfor delay '00:00:15'
    select * from studentMarks where ID in (1,2)
    rollback

Now here what will happen, if there is any outside transaction tries to modify the data which affect the Transaction one query then, the outside transaction will go on wait for getting update lock until transaction1 complete its operation.



Post Reference: Vikram Aristocratic Elfin Share

Friday, June 13, 2014

What does TimeStamp/Rowversion does?

Rowversion /Timestamp is a datatype which stores 8byte binary number. Each time any insert/update operation performed on a table having Rowversion column, the value of row version for inserted or updated rows changes to the latest counter of Rowversion.

A table can have maximum of only one column as rowversion datatype.
Timestamp is synonym to the Rowversion data type.

Lets see with an example, how we can use rowversion as a column in our table.

create table RowVersion_TB
(col1 int, col2 int, timestamp);
Command(s) completed successfully.

Now we have our table created with  rowversion datatype as one of the column. Lets insert few records in it.

insert into RowVersion_TB (col1, col2)
select 1,100 union all
select 2,200 union all
select 3,300

Lets query the table to see what values appears in the rowversion field.

select * from RowVersion_TB
col1        col2        timestamp
----------- ----------- ------------------
1           100         0x00000000000007D4
2           200         0x00000000000007D5
3           300         0x00000000000007D6

(3 row(s) affected)

Alright , the value of rowversion column is in increamented order. Lets update a row say where col1=3 and see how it affect rowversion data.

update RowVersion_TB
set col2=400
where col1=3

select * from RowVersion_TB
col1        col2        timestamp
----------- ----------- ------------------
1           100         0x00000000000007D4
2           200         0x00000000000007D5
3           400         0x00000000000007D7

(3 row(s) affected)

See the rowversion value changed when we change the data of col2 to 07D7

Lets again update the first row of the table to see, the changed value of Rowversion

update RowVersion_TB
set col2=10
where col1=1

select * from RowVersion_TB
col1        col2        timestamp
----------- ----------- ------------------
1           10          0x00000000000007D8
2           200         0x00000000000007D5
3           400         0x00000000000007D7

(3 row(s) affected)

Ah, notice that col1 1 has most updated Rowversion value. So most recently updated record has latest rowversion information.

Coder always have reason to avoid outing and shoping! J