- We need the ability to control how
transactions are run in a multiuser database.
- A transaction is a set of read
and write operations that must either
commit or abort.
- Consider the following transaction that
reserves a seat on an airplane flight and
changes the customer:
1. Read customer information
2. Write reservation information
3. Write charges
- Suppose that after the second step, the
database crashes. Or for some reason, changes
can not be written...
- Transactions can either reach a commit
point, where all actions are permanently saved
in the database or they can
abort in which case none of the actions
are saved.
- Another way to say this is transactions are
Atomic. All operations in a transaction
must be executed as a single unit - Logical
Unit of Work.
- Consider two users, each executing similar
transactions:
Example #1:
User A User B
Read Salary for emp 101 Read Salary for emp 101
Multiply salary by 1.03 Multiply salary by 1.04
Write Salary for emp 101 Write Salary for emp 101
Example #2:
User A User B
Read inventory for Prod P200 Read inventory for Prod P200
Decrement inventory by 5 Decrement inventory by 7
Write inventory for Prod P200 Write inventory for Prod P200
- First, what should the values for salary (in
the first example) really be ?
- The DBMS must find a way to execute these two
transactions concurrently and ensure
the result is what the users (and designers)
intended.
- These two are examples of the Lost
Update or Concurrent Update
problem. Some changes to the database can be
overwritten.
- Consider how the operations for user's A and B
might be interleaved as in example #2.
Assume there are 10 units in inventory for
Product P200:
Time Operation TA TB Value of P200
1 Begin Transaction TA Begin 10
2 Begin Transaction TB Begin 10
3 TA Read inventory P200 Read(P200) 10
4 TB Read inventory P200 Read(P200) 10
5 TA Decrement inventory P200=P200-2 10
6 TB Decrement inventory P200=P200-3 10
7 TA Wrtie inventory Write(P200) 8 (dirty)
8 TB Wrtie inventory Write(P200) 7 (dirty)
9 TA Commit Commit 7 (dirty)
10 TB Commit Commit 7 (clean)
Or something similar like:
Time Operation TA TB Value of P200
1 Begin Transaction TA Begin 10
2 TA Read inventory P200 Read(P200) 10
3 TA Decrement inventory P200=P200-2 10
4 TA Wrtie inventory Write(P200) 8 (dirty)
5 TA Commit Commit 8 (clean)
6 Begin Transaction TB Begin 8
7 TB Read inventory P200 Read(P200) 8
8 TB Decrement inventory P200=P200-3 8
9 TB Wrtie inventory Write(P200) 5 (dirty)
10 TB Commit Commit 5 (clean)
- In the first case, the incorrect amount (7)
is written to the database. This is called the
Lost Update problem because we lost the
update from TA - it was overwritten by T2.
- The second example works because we let TA write
the new value of Product P200 before TB can read it.
- Here is another example.
Time Operation TA TB Value of P200
1 Begin Transaction TA Begin 10
2 TA Read inventory P200 Read(P200) 10
3 TA Decrement inventory P200=P200-2 10
4 TA Wrtie inventory Write(P200) 8 (dirty)
5 Begin Transaction TB Begin 8
6 TB Read inventory P200 Read(P200) 8
7 TA Aborts/Rollback Abort 10 (clean)
8 TB Decrement inventory P200=P200-3 10
9 TB Wrtie inventory Write(P200) 5 (dirty)
10 TB Commit Commit 5 (clean)
- The reason we get the wrong final result
is becaue TA had not committed before TB was allowed
to read a value TA had written.
This is called the uncomitted dependency or Dirty read problem.
- Now consider a transaction trying to find a SUM of all units in inventory
while another transaction is trying to update inventory
(d) means direty and (c) means clean.
Time Operation TA TB P200 P300 P400 Sum
1 Begin Transaction TA Begin 10 15 20 0
2 TA Read inventory P200 Read(P200) 10 15 20 0
3 TA Sum up inventory Sum=Sum+P200 10 15 20 10
4 TA Read inventory P300 Read(P300) 10 15 20 10
5 TA Sum up inventory Sum=Sum+P300 10 15 20 25
6 Begin Transaction TB Begin 10 15 20 25
7 TB Read inventory P200 Read(P200) 10 15 20 25
8 TB Decrement inventory P200=P200-3 10 15 20 25
9 TB Wrtie inventory Write(P200) 7(d) 15 20 25
10 TA Read inventory P400 Read(P400) 7(d) 15 20 45
11 TA Sum up inventory Sum=Sum+P400 7(d) 15 20 45
12 TB Commit Commit 7(c) 15 20 45
13 TA Commit Commit 7(c) 15 20 45
- The final sum is not correct. This happened because
TB was allowed to write a data item that TA was trying
to use in its work. This is called the incorrect analysis problem
- Suppose we have a transaction that says if P300 is greater than P200
then decrement P300. At the same time another transaction is
trying to update P300.
Time Operation TA TB P200 P300
1 Begin Transaction TA Begin 10 15
2 TA Read inventory P200 Read(P200)=10 10 15
3 TA Read inventory P300 Read(P300)=15 10 15
4 TB Begin Transaction Begin 10 15
5 TB Read inventory P300 Read(P300) 10 15
6 TB Decrement inventory P300=P300-10 10 15
7 TB Wrtie inventory Write(P300) 10 5 (d)
8 TB Commit Commit 10 5 (c)
9 TA P300 > P200 so update 10 5 (c)
10 TA Read inventory P200 Read(P200)=10 10 5
11 TA Read inventory P300 Read(P300)=5 10 5
12 TA Decrement inventory P300=P300-5 10 5
13 TA Wrtie inventory Write(P300) 10 0 (d)
14 TA Commit Commit 10 0 (c)
- The two read operations that TA performas at time 3 and
time 11 get different results.
- This is called the non-repeatable read problem
(or fuzzy read problem).