Uploaded by Rhythm

CSE 5109 Lab 02

advertisement
CSEL-5109 – Advanced Database and Management System Lab
Laboratory 02: Transaction-Atomicity, Isolation, Consistency, and Durability
Submission Due: End of laboratory class, submit the file on Google Classroom/Google Form
before the beginning of next laboratory class.
Total Marks
= X marks for Y weeks
Marks will be given only to students who attend and participate during 2/3-hour laboratory
class. Submission on Google Classroom/Google Form is mandatory as evidence of
participation.
Description of the laboratory exercise:
Requirements:
1. Windows/MAC/Linux Operating System
2. PostgreSQL
Transaction
A transaction is a single logical unit of work which accesses and possibly modifies the contents of a
database. Transactions access data using read and write operations. In order to maintain
consistency in a database, before and after the transaction, certain properties are followed. These
are called ACID properties.
Atomicity
By this, we mean that either the entire transaction takes place at once or doesn’t happen at all.
There is no midway i.e. transactions do not occur partially. Each transaction is considered as one unit
and either runs to completion or is not executed at all. It involves the following two operations.
Abort: If a transaction aborts, changes made to database are not visible.
Commit: If a transaction commits, changes made are visible.
Atomicity is also known as the ‘All or nothing rule’. Consider the following transaction T consisting
of T1 and T2: Transfer of 100 from account X to account Y.
If the transaction fails after completion of T1 but before completion of T2.( say, after write(X) but
before write(Y)), then amount has been deducted from X but not added to Y. This results in an
inconsistent database state. Therefore, the transaction must be executed in entirety in order to
ensure correctness of database state.
Prepared by: Md Ashraf Uddin, PhD (Australia)
Associate Professor, Dept. of CSE, JnU
Consistency
This means that integrity constraints must be maintained so that the database is consistent before
and after the transaction. It refers to the correctness of a database. Referring to the example above,
The total amount before and after the transaction must be maintained.
Total before T occurs = 500 + 200 = 700.
Total after T occurs = 400 + 300 = 700.
Therefore, database is consistent. Inconsistency occurs in case T1 completes but T2 fails. As a result
T is incomplete.
Isolation
This property ensures that multiple transactions can occur concurrently without leading to the
inconsistency of database state. Transactions occur independently without interference. Changes
occurring in a particular transaction will not be visible to any other transaction until that particular
change in that transaction is written to memory or has been committed. This property ensures that
the execution of transactions concurrently will result in a state that is equivalent to a state achieved
these were executed serially in some order.
Let X= 500, Y = 500.
Consider two transactions T and T”.
Suppose T has been executed till Read (Y) and then T’’ starts. As a result , interleaving of operations
takes place due to which T’’ reads correct value of X but incorrect value of Y and sum computed by
T’’: (X+Y = 50, 000+500=50, 500) is thus not consistent with the sum at end of transaction:
T: (X+Y = 50, 000 + 450 = 50, 450).
This results in database inconsistency, due to a loss of 50 units. Hence, transactions must take place
in isolation and changes should be visible only after they have been made to the main memory.
Durability:
Prepared by: Md Ashraf Uddin, PhD (Australia)
Associate Professor, Dept. of CSE, JnU
This property ensures that once the transaction has completed execution, the updates and
modifications to the database are stored in and written to disk and they persist even if a system
failure occurs. These updates now become permanent and are stored in non-volatile memory. The
effects of the transaction, thus, are never lost.
The ACID properties, in totality, provide a mechanism to ensure correctness and consistency of a
database in a way such that each transaction is a group of operations that acts a single unit,
produces consistent results, acts in isolation from other operations and updates that it makes are
durably stored.
Isolation Level
Isolation levels define the degree to which a transaction must be isolated from the data
modifications made by any other transaction in the database system. A transaction isolation level is
defined by the following phenomena



Dirty Read – A Dirty read is a situation when a transaction reads data that has not yet been
committed. For example, Let’s say transaction 1 updates a row and leaves it uncommitted,
meanwhile, Transaction 2 reads the updated row. If transaction 1 rolls back the change,
transaction 2 will have read data that is considered never to have existed.
Non Repeatable read – Non Repeatable read occurs when a transaction reads the same row
twice and gets a different value each time. For example, suppose transaction T1 reads data.
Due to concurrency, another transaction T2 updates the same data and commit, Now if
transaction T1 rereads the same data, it will retrieve a different value.
Phantom Read – Phantom Read occurs when two same queries are executed, but the rows
retrieved by the two, are different. For example, suppose transaction T1 retrieves a set of
rows that satisfy some search criteria. Now, Transaction T2 generates some new rows that
match the search criteria for transaction T1. If transaction T1 re-executes the statement that
reads the rows, it gets a different set of rows this time.
Based on these phenomena, The SQL standard defines four isolation levels :




Read Uncommitted – Read Uncommitted is the lowest isolation level. In this level, one
transaction may read not yet committed changes made by other transactions, thereby
allowing dirty reads. At this level, transactions are not isolated from each other.
Read Committed – This isolation level guarantees that any data read is committed at the
moment it is read. Thus it does not allow dirty read. The transaction holds a read or write
lock on the current row, and thus prevents other transactions from reading, updating, or
deleting it.
Repeatable Read – This is the most restrictive isolation level. The transaction holds read
locks on all rows it references and writes locks on referenced rows for update and delete
actions. Since other transactions cannot read, update or delete these rows, consequently it
avoids non-repeatable read.
Serializable – This is the highest isolation level. A serializable execution is guaranteed to be
serializable. Serializable execution is defined to be an execution of operations in which
concurrently executing transactions appears to be serially executing.
Prepared by: Md Ashraf Uddin, PhD (Australia)
Associate Professor, Dept. of CSE, JnU
The Table is given below clearly depicts the relationship between isolation levels, read phenomena,
and locks :
Anomaly Serializable is not the same as Serializable. That is, it is necessary, but not sufficient that a
Serializable schedule should be free of all three phenomena types.
Practical Example:
Download PostgreSQL from the following link and install the PostgreSQL on your computer.
https://www.postgresql.org/
Open SQL Shell and keep pressing Enter until password is asked and provide the password that you
used while installing PostgreSQL.
Create a database on PostgreSQL and select your database.
postgres=# CREATE DATABASE aciddb;
postgres=# \c aciddb
Create the following two tables
Prepared by: Md Ashraf Uddin, PhD (Australia)
Associate Professor, Dept. of CSE, JnU
aciddb =# create table products (pid serial primary key, name text, price float, inventory integer);
aciddb =# create table sales( saleid serial primary key, pid integer, price float, quantity integer);
aciddb =# insert into products (name, price, inventory) values(‘phone’, 999.9, 100);
aciddb =# select*from products;
pid | name | price | inventory
-----+-------+--------+----------1 | Phone | 999.99 |
100
(1 row)
Atomicity
Let’s begin the transaction and overserve the effect of atomicity. Do not commit the transaction.
aciddb =# begin transaction;
BEGIN
aciddb =*# update products set inventory = inventory - 10;
UPDATE 1
aciddb =*# insert into sales (pid, price, quantity) values(1,999.99, 10);
INSERT 0 1
aciddb =*# select* from products;
pid | name | price | inventory
-----+-------+--------+----------1 | Phone | 999.99 |
90
(1 row)
At this stage, close the window/terminal and open the SQL Shell again. Issue the following
command and observe the outcome of the query. Did the update persist in the database?
aciddb =*# select* from products;
aciddb =*# select* from sales;
Prepared by: Md Ashraf Uddin, PhD (Australia)
Associate Professor, Dept. of CSE, JnU
Let’s begin the transaction again and commit the transaction after updating both products
and sales table.
aciddb =# begin transaction;
BEGIN
aciddb =*# update products set inventory = inventory - 10;
UPDATE 1
aciddb =*# insert into sales (pid, price, quantity) values(1,999.99, 10);
INSERT 0 1
aciddb =*# select* from products;
pid | name | price | inventory
-----+-------+--------+----------1 | Phone | 999.99 |
90
(1 row)
aciddb =*# commit;
COMMIT
aciddb =*# select* from products;
aciddb =*# select* from sales;
Did you notice the changes in both tables: products and sales?
Isolation
Let’s first insert several entities into sales table to show the effect of isolation.
aciddb =# insert into sales (pid, price, quantity) values(1, 999.99, 5);
INSERT 0 1
aciddb =# insert into sales (pid, price, quantity) values(1, 999.99, 5);
INSERT 0 1
aciddb =# insert into sales (pid, price, quantity) values(2, 99.99, 10);
INSERT 0 1
Prepared by: Md Ashraf Uddin, PhD (Australia)
Associate Professor, Dept. of CSE, JnU
aciddb =# insert into sales (pid, price, quantity) values(2, 89.99, 10);
INSERT 0 1
aciddb =# insert into sales (pid, price, quantity) values(2, 79.99, 20);
INSERT 0 1
aciddb =# select*from sales;
saleid | pid | price | quantity
--------+-----+--------+---------1 | 1 | 999.99 |
10
2 | 1 | 999.99 |
5
3 | 1 | 999.99 |
5
4 | 2 | 99.99 |
10
5 | 2 | 89.99 |
10
6 | 2 | 79.99 |
20
(6 rows)
Now, insert a row into products table and see the effect of rollback
aciddb =# insert into products(name,price, inventory) values('Earbuds', 99.9, 160);
INSERT 0 1
aciddb =# select*from products;
pid | name | price | inventory
-----+---------+--------+----------1 | Phone | 999.99 |
2 | Earbuds | 99.9 |
90
160
(2 rows)
aciddb =# select*from products;
Prepared by: Md Ashraf Uddin, PhD (Australia)
Associate Professor, Dept. of CSE, JnU
pid | name | price | inventory
-----+-------+--------+----------1 | Phone | 999.99 |
90
(1 row)
aciddb =# select*from sales;
saleid | pid | price | quantity
--------+-----+--------+---------1 | 1 | 999.99 |
10
(1 row)
aciddb =*# rollback;
ROLLBACK
Isolation Level: Repeatable Read
In this example, we see how to isolate transaction using repeatable read isolation level. We
will open two terminal or windows and execute the following commands to see the effect of
repeatable read.
Terminal/window 1
aciddb =# begin transaction isolation level repeatable read;
BEGIN
aciddb =*# select pid, price, quantity from sales;
pid | price | quantity
-----+--------+---------1 | 999.99 |
10
1 | 999.99 |
5
1 | 999.99 |
5
2 | 99.99 |
10
2 | 89.99 |
10
2 | 79.99 |
20
Prepared by: Md Ashraf Uddin, PhD (Australia)
Associate Professor, Dept. of CSE, JnU
1 | 99.99 |
10
(7 rows)
aciddb =*# select pid, count(pid) from sales group by pid;
pid | count
-----+------2|
3
1|
4
(2 rows)
Go to Terminal 2
aciddb =*# select*from sales;
saleid | pid | price | quantity
--------+-----+--------+---------1 | 1 | 999.99 |
10
2 | 1 | 999.99 |
5
3 | 1 | 999.99 |
5
4 | 2 | 99.99 |
10
5 | 2 | 89.99 |
10
6 | 2 | 79.99 |
20
7 | 1 | 99.99 |
10
(7 rows)
aciddb =*# select pid, count(pid) from sales group by pid;
pid | count
-----+------2|
3
Prepared by: Md Ashraf Uddin, PhD (Australia)
Associate Professor, Dept. of CSE, JnU
1|
4
(2 rows)
aciddb =*# commit;
COMMIT
aciddb =# select pid, count(pid) from sales group by pid;
pid | count
-----+------2|
3
1|
6
(2 rows)
Terminal/window 2
aciddb =# begin transaction;
BEGIN
aciddb =*# insert into sales( pid, price, quantity) values(1, 99.99, 10);
INSERT 0 1
aciddb =*# update products set inventory = inventory-10 where pid =1;
UPDATE 1
aciddb =*# commit;
COMMIT
Go to Terminal 2
aciddb =# insert into sales( pid, price, quantity) values(1, 99.99, 10);
INSERT 0 1
aciddb =# update products set inventory = inventory-10 where pid =1;
UPDATE 1
Prepared by: Md Ashraf Uddin, PhD (Australia)
Associate Professor, Dept. of CSE, JnU
aciddb =# begin transaction;
BEGIN
aciddb =*# insert into sales( pid, price, quantity) values(1, 99.99, 10);
INSERT 0 1
aciddb =*# update products set inventory = inventory-10 where pid =1;
UPDATE 1
aciddb =*# commit;
COMMIT
aciddb =#
Repeatable Read
The following example shows you the effect of repeatable read.
Terminal/window 1
aciddb =*# begin transaction isolation level repeatable read;
aciddb =*# select pid, count(pid) from sales group by pid;
Go to Terminal/window2
aciddb =*# select pid, price, quantity from sales;
aciddb =*# select pid, count(pid) from sales group by pid;
Go to Terminal 2
aciddb =*# commit;
aciddb =*# select pid, count(pid) from sales group by pid;
Terminal/window 2
aciddb =*# begin transaction;
aciddb =*# insert into sales (pid, price, quantity) values(1,99.99,10);
aciddb =*# update products set inventory = inventory-10 where pid =1;
aciddb =*# commit;
Go to Terminal/window 1
aciddb =*# select pid, count(pid) from sales group by pid;
Prepared by: Md Ashraf Uddin, PhD (Australia)
Associate Professor, Dept. of CSE, JnU
Durability
To examine the durability, we will insert a row in terminal 2 and after committing we will observe
the outcome in terminal 1. Likewise, we will insert a row in terminal 1 and will not commit. After
that we will observe the outcome of the insertion in terminal 2.
Terminal 1
aciddb =*# Select* from products;
Terminal 2
aciddb =*# Insert into products (name, price, inventory) values (‘TV’, 3000, 10);
aciddb =*# Select* from products;
aciddb =*# Commit;
Go to Terminal 1
Phantom Reads
This example shows the impact of phantom reads and solution of the phantom reads. Open two
terminal and issues the following commands.
Terminal 1
aciddb =*# Begin transaction;
aciddb =*# Select* from sales;
aciddb =*# Select pid, sum(price) from sales group by pid;
Go to terminal 2
aciddb =*# Select pid, sum(price) from sales group by pid;
aciddb =*# Select* from sales;
Rollback;
aciddb =*# Begin transaction isolation level serializable;
aciddb =*# Select* from sales;
Go to Terminal 2
aciddb =*# Commit;
aciddb =*# Select* from sales;
Prepared by: Md Ashraf Uddin, PhD (Australia)
Associate Professor, Dept. of CSE, JnU
Terminal 2
aciddb =*# insert into sales (pid, price, quantity) values(1, 79.99, 30);
aciddb =*# insert into sales (pid, price, quantity) values(1, 79.99, 30);
//aciddb =*# Insert into sales (pid, price, date) values (1, 15, ‘feb-7-2021’);
//aciddb =*# Insert into sales (pid, price, date) values (1, 15, ‘feb-7-2021’);
Go to Terminal 1
Serializable vs Repeatable Read
aciddb =*# Create table test( id integer, t text);
aciddb =*# Insert into test(id, t) values(12, ‘a’);
aciddb =*# Insert into test(id, t) values(13, ‘a’);
aciddb =*# Insert into test(id, t) values(10, ‘b’);
aciddb =*# Insert into test(id, t) values(11, ‘b’);
aciddb =*# select*from test;
Terminal 1
aciddb =*# Begin transaction isolation level repeatable read;
aciddb =*# Update test set t = ‘a’ where t = ‘b’;
aciddb =*# Select*from test;
aciddb =*# Commit
aciddb =*# Select*from test;
aciddb =*# Begin transaction isolation level serializable;
aciddb =*# Update test set t = ‘a’ where t = ‘b’;
aciddb =*# Select*from test;
aciddb =*# Rollback;
aciddb =*# Begin transaction isolation level serializable;
aciddb =*# Update test set t = ‘a’ where t = ‘b’;
Prepared by: Md Ashraf Uddin, PhD (Australia)
Associate Professor, Dept. of CSE, JnU
aciddb =*# Select*from test;
Terminal 2
aciddb =*# Begin transaction isolation level repeatable read;
aciddb =*# Update test set t = ‘b’ where t = ‘a’;
aciddb =*# Begin transaction isolation level repeatable read;
aciddb =*# Update test set t = ‘b’ where t = ‘a’;
aciddb =*# Commit;
aciddb =*# Select* from test;
aciddb =*# Begin transaction isolation level serializable;
aciddb =*# Update test set t = ‘b’ where t = ‘a’;
aciddb =*# commit;
Prepared by: Md Ashraf Uddin, PhD (Australia)
Associate Professor, Dept. of CSE, JnU
Prepared by: Md Ashraf Uddin, PhD (Australia)
Associate Professor, Dept. of CSE, JnU
Download