0% found this document useful (0 votes)
16 views

Acid and Transactions

Uploaded by

Long Mai
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

Acid and Transactions

Uploaded by

Long Mai
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

Chapter 2: Data preservation, security and database optimisation

• The DBMS (or a part of it) crashes while executing a set of operations. Because the
operations were not successfully completed, the database is left in an unknown,
unpredictable and possibly damaged state.
• Two applications, with different users change the same part of the database at the
same time. Because neither is aware of the other, some of the changes made by one
application can be overwritten with old data by the other. If the two sets of updates
are complicated, the database can easily end up in an incorrect, unpredictable or
inconsistent state.
• An unauthorised user gets access to the database, either seeing private information
or deliberately altering the database to leave it in a compromised state.
These three scenarios illustrate three important data protection issues:
• Data recovery
• Concurrency control
• Security
We will consider these separately in this chapter. These issues are generic – they affect
any data management system that permits multiple users and simultaneous, concur-
rent interactions – and, as a result, the resolutions of them are also often applicable be-
yond relational database systems.
Some of the more generic issues, especially those of recovery and concurrency control
will be revisited when we look at alternative models to the relational database.

Data recovery
Most people have had a computer system fail at some point, whether because a piece of
software crashed, or because power was lost to a machine without battery power. At
that point, it is possible that files that were being worked on at the time are lost and un-
recoverable. It may not be a disaster, however – perhaps the user saved their work just
before the trouble started. More helpfully, perhaps the operating system or the soft-
ware that was being used at the time had automatically saved versions of all current
files and could retrieve them when the software was restarted.
This situation illustrates some common aspects of data recovery:
• Data recovery requires duplication of data – data redundancy – so that there are
backup copies of any given piece of information at all times. This redundant data
must be stored on non-volatile storage, ‘permanent support’, so that it can survive
the host computer going through a power cycle.
• The more robust the data recovery features used, the less efficient the system be-
comes. For example, if a word processor automatically saves a document every few
seconds or on each keypress, that requires processor and disk overhead. Depend-
ing on the capabilities of the host system, that may be cause a noticeable, even an-
noying, lag.
A system crash that occurs during the use of a database system can lead to the loss of
important data and to inconsistencies in the data that is left behind. The ability to re-
cover a correct, consistent state is vital.
Data recovery Data recovery of a database is the ability to restore its content and functionality
following a system failure to an earlier and correct state.
Database systems must be able to handle large amounts of complex data and many
concurrent interactions. That means that the data recovery mechanisms that they use
are necessarily more elaborate and sophisticated than a simple automatic save func-

5
Chapter 2: Data preservation, security and database optimisation
tion. Still, they are based on similar principles – most importantly the requirement for
redundancy.
The database must maintain not only its current content, but also information about a
state that is known to be correct that can be used in the case where a system crash re-
sults in damage to its main resource. This redundancy has to be on non-volatile storage,
or it would be lost in the crash as well.
Ideally, the user should be unaware of the details of the process – if a system crash oc-
curs, the DBMS should be able to restore its database to a correct state without an ad-
ministrator having to be involved. Counterintuitively perhaps, this means that a DBMS
and the logical structure of the data it stores should appear the same whether data re-
covery is supported or not. Redundancy occurs at the physical level only, and is not re-
flected at all at the logical level.
The mechanisms of data recovery are based on the concept of the transaction.

Transactions
Consider a database for a company that keeps information about the programmers they
employ and the projects they work on. The information is stored in two tables, illus-
trated in figure 2.1 below.
Programmers
PID Name SalaryBand NumberOfProjects
MB1 M. Baker 22 2
GK1 G. Kovacs 24 1
JL1 J. Lilly 28 3

Assignments
PID Project HoursPerWeek
MB1 Mobile 24
MB1 UserTesting 11
GK1 UserTesting 30
JL1 Mobile 12
JL1 Parser 6
JL1 UIDesign 12
Figure 2.1. Two tables in a company’s database.

Suppose that a new programmer, B. Eich, has been employed and has had three pro-
jects assigned to him. The database must be updated accordingly. The SQL insertion
operations required to do that would be something like this:
INSERT INTO Programmers VALUES ("BE1", "B. Eich", 20, 3);
INSERT INTO Assignments VALUES ("BE1", "Parser", 12);
INSERT INTO Assignments VALUES ("BE1", "UIDesign", 12);
INSERT INTO Assignments VALUES ("BE1", "Mobile", 12);
If an error occurred after the first two insert operations were performed successfully,
but before the others were even started, the database will end up both incorrect – it
does not reflect the current state of the system being modelled – and inconsistent – it
contains data in one part that contradicts the information in another part. Since the
Programmers table indicates that B. Eich has three projects, but the Assignments table
only shows one, there is an inconsistency between the tables.

6
Chapter 2: Data preservation, security and database optimisation

Activity. What effect does the order of operations have on this problem? Is
there a way of reordering these commands so that, if they are not all completed,
the database is consistent? Is there a different set of insertions that would be
more robust? Is there anything about the data model used that makes this ex-
ample particularly susceptible to inconsistencies?

What this example illustrates is that there are situations where a set of operations only
make sense if they are performed together – the performance of only a part of them
would make the database incorrect, inconsistent or both. In other words, the opera-
tions represent a single logical unit of work.
The problem arises because many logical units of work cannot be expressed in just one
SQL statement that is guaranteed either to run as a whole or not be executed at all. The
example above can be expressed as four statements as above, or two statements:
INSERT INTO Programmers VALUES ("BE1", "B. Eich", 20, 3);
INSERT INTO Assignments VALUES ("BE1", "Parser", 12),
("BE1", "UIDesign", 12), ("BE1", "Mobile", 12);
It is impossible, however, to achieve the same result with a single statement, and yet
they make no sense separately.
Transaction A transaction is a sequence of database operations that represent a logical unit of work.
The database should be in a consistent state both before they start and after they are
completed.
Note that during the performance of a transaction – between its first operation and its
last one – the database can, and often will, be in an inconsistent state. It is only between
transactions that the database is guaranteed to be in a consistent state (provided the
user gives consistent data).
If a system supports transactions, then it should guarantee that all the constituent op-
erations of the transaction will be executed once the transaction is initiated. Of course,
if that requirement were achievable – if we could guarantee that every operation that
started would also finish – then we would have less need for transactions in the first
place. Instead, there is a weaker requirement, the so-called principle of transaction
processing support:
If some, but not all, operations of a transaction are performed and a failure occurs before
the planned termination of the transaction, then the DBMS must guarantee that those op-
erations that have been carried out already will be undone.
This principle provides an all-or-nothing feature that ensures the atomicity of a trans-
action – a transaction cannot be split, at least in terms of its execution, into smaller
components. Using transactions, the database can be seen to evolve from one correct
state to another with intermediate states concealed, and transitions only carried out
using successfully executed transactions.

Implementation. Most modern RDBMS implementations support transactions,


however there are may be some restrictions. For example, to use transactions
in MySQL, you will need to ensure that your tables use the InnoDB storage en-
gine, not the older MyISAM.

The module of a DBMS that implements transaction support is called the transaction
manager. The transaction manager supports two mechanisms:
• COMMIT TRANSACTION – guarantees the performance of all the corresponding op-
erations of the transaction.
• ROLLBACK TRANSACTION – rolls back, or undoes, operations that have been per-
formed within the transaction so far – for when an error occurs.

7
Chapter 2: Data preservation, security and database optimisation
In pseudocode, a transaction might look something like this:
START TRANSACTION;
INSERT ...
UPDATE ...
...
IF no problems
THEN COMMIT TRANSACTION;
ELSE ROLLBACK TRANSACTION;
So the transaction has a single beginning, but two possible ends – either the whole se-
quence of operations is committed to the database, or everything is undone.
From the example we gave earlier, we could add the programmer and his new assign-
ments more safely by placing the necessary operations inside a transaction (still in
pseudocode):
START TRANSACTION;
INSERT INTO Programmers VALUES ("BE1", "B. Eich", 20, 3);
INSERT INTO Assignments VALUES ("BE1", "Parser", 12);
INSERT INTO Assignments VALUES ("BE1", "UIDesign", 12);
INSERT INTO Assignments VALUES ("BE1", "Mobile", 12);
IF no problems
THEN COMMIT TRANSACTION;
ELSE ROLLBACK TRANSACTION;
Crucially, the DBMS keeps a log or journal of each operation as it carries out these ac-
tions, allowing the system to keep track of what has and has not been carried out.
In general, a DBMS is likely to copy some or all of any database into a buffer in volatile
memory and perform operations on those copies – largely for reasons of speed. At cer-
tain points, these copies are written to non-volatile storage. If a system crashes when
only the buffers have been altered by an operation, the update will be lost. Because of
this, it is vital that the log of operations is recorded to non-volatile memory until it can
be written permanently to disk.
The information recorded in the log allows the DBMS to:
• Undo any performed operation if an error occurs before its transaction is complet-
ed.
• Perform all operations of a transaction on non-volatile storage even if all the opera-
tions were previously lost from volatile memory – as would be the case in a system
crash.
As we noted earlier, if all the operations of a transaction are correctly performed, with
no errors or interruptions, then a COMMIT statement can be issued. Completing a
COMMIT statement guarantees that all the operation of the transaction can be per-
formed on non-volatile storage – even if the data is not written directly, the log has all
the information necessary.
The moment when a COMMIT statement is issued is called a commit point or sync point.
Once a commit point is reached, it is certain that no update operation from the corre-
sponding transaction will have to be undone – the changes made are permanent. Be-
tween a commit point and the beginning of the next transaction, the database is availa-
ble for any retrieve operations. Between a START TRANSACTION statement and a COM-

8
Chapter 2: Data preservation, security and database optimisation
MIT or ROLLBACK, the database is likely to be in an incorrect and inconsistent state and
some or all operations from outside the transaction are likely to be blocked. Figure 2.2
illustrates the succession of states and the restriction of access during transactions.
Figure 2.2. Since, during a transaction’s execution, the database may be in an inconsistent state, access
must be restricted until the transaction has been committed and its operations are complete.

If something goes wrong, the ROLLBACK statement is issued, and the database has to
recover its previous state. This mechanism is called transaction recovery and is shown
in figure 2.3. Clearly, if full database access had been available to other users during the
aborted transaction, wrong information could have propagated elsewhere.

Figure 2.3. When Transaction 2 fails for some reason, it triggers a ROLLBACK, and the previous state of
the database is restored.

We have said that a transaction is the logical unit of work. From the behaviour de-
scribed above, it can also be said that the transaction is the unit of recovery.
The log plays an important part in this process, but it can only be used in transaction
processing if the relevant information about each operation of a transaction is com-
pletely entered into the log before the operation starts. This rule is known as the write-
ahead rule.
We have assumed so far that the constituent operations of a transaction can be consid-
ered to be atomic, that is, that they cannot be divided, and that they either succeed or
fail in entirely. This is an assumption that is guaranteed valid by lower level mecha-
nisms of the DBMS, and is not regarded as a part of transaction management.
The use of transactions makes it possible for DBMS developers to make certain im-
portant guarantees of reliability. These guarantees were formalised over the course of
the 1970s and 1980s. One important paper on the subject is Jim Gray’s ‘The Transac-
tion Concept: Virtues and Limitations’, presented at the Seventh International Confer-
ence on Very Large Databases in 19811 which laid the groundwork for the form in which
these guarantees are best known – the ACID properties. The ACID properties are four
properties that are central to discussions of data recovery:
• Atomicity – either all operations in a transaction are performed or none of them
are.
• Consistency – the transaction mechanism guarantees that the DB evolves from one
consistent state to another.

1This paper is currently available in full at http://research.microsoft.com/en-


us/um/people/gray/papers/theTransactionConcept.pdf.

9
Chapter 2: Data preservation, security and database optimisation
• Isolation – transactions are isolated from one another, so that when a transaction
is performed on a database, no other transaction that might affect the same data
can be performed at the same time.
• Durability – once a transaction has been committed, the changes it makes are
guaranteed to be performed physically (i.e. in non-volatile storage).
These properties inform not only important aspects of database recovery but, as we
shall see later, they are a key issue in comparing database models that present alterna-
tives to relational theory.

Database recovery
So far, we have considered a single transaction on a database. If an error occurs during
a transaction, the DBMS recovers by undoing the operations that have been performed.
If the database is only used by one person at a time, then this is straightforward, but a
database is a shared resource. It is likely that a DBMS will have to deal with several
transactions at once.
A transaction can fail because of an error, but it can also fail because of a system failure
either of hardware or software. In the case of hardware failure, it is possible that the
non-volatile memory is itself damaged, which brings additional complications, but for
the present, we will consider the case of a ‘soft crash’, that results in the database sys-
tem failing, but all storage written to disk remaining accessible afterwards.
If a DBMS is processing several transactions when a failure occurs, all the transactions
that were in progress at the time of the crash must be dealt with appropriately. As in
the case of a single-transaction, it is the information kept in the log that makes this pos-
sible.
Much of the normal running of a database happens in in-memory buffers – the DBMS
takes a copy of the data it needs and manipulates it in internal memory. At certain
points in time (at the checkpoint), the system automatically writes (‘force writes’) all
the data that has changed onto the permanent support. At the same time, a list of all the
transactions that were in progress at the time of writing is recorded in a log called the
checkpoint record. Then the system continues processing data until the next force writ-
ing point, and so on.
The implications of a crash on any given transaction depend on its status both at the
time of the crash and at the time of the last force write. Figure 2.4 illustrates the five
types of transaction states.

Figure 2.4. A system failure has occurred at time point tp2. The last save was at tp1. This diagram illus-
trates the different stages of operation of five transactions (T1-5) before the crash.

In this diagram, a failure has occurred at time point tp2, and the most recent check-
point was at time tp1. The possible situations that a transaction can be in as a result
are:

10
Chapter 2: Data preservation, security and database optimisation
• T1 – Completely successful before tp1. It was written on permanent support at tp1
and its successful completion has been recorded in the log.
• T2 – Initiated before tp1 and completed successfully before tp2, however, it was
completed after tp1, and so its successful completion was written to the log, but, we
cannot guarantee that all operations performed after tp1 have been written to
permanent support, so this operation transaction may be complete in the logs, but
not on disk.
• T3 – Initiated before tp1, but not completed at the time of the failure. Only its initia-
tion was written to the log, so the log will be incomplete for this transaction.
• T4 – Initiated after tp1, but completed before tp2, so its successful completion was
recorded in the log, but we cannot guarantee that the data has been committed to
permanent support.
• T5 – Initiated after tp1 and incomplete at the time of the crash. Only its initiation
was written to the log, so the log record for this transaction will be incomplete.
After the system restarts, and before it begins fresh data processing, the DBMS must re-
cover from the failure. The operations that it undertakes are:
• Transactions of type T1 can be disregarded. They have not only completed success-
fully, but their results have been written on recoverable, non-volatile media.
• Transactions of type T2 and T4 have to be repeated based on the information in the
log. This is because they completed successfully, but we cannot guarantee that the
results of their operation were saved to permanent support.
• Transactions of type T3 and T5 must be undone, because they were not successful-
ly completed at the time of the crash. The log does not contain sufficient infor-
mation in order for them to be re-initiated.

Transactions in SQL
SQL supports transaction-based recovery using START TRANSACTION, COMMIT and
ROLLBACK commands, and these are generally reliably implemented in most implemen-
tations.
The standard also provides much more fine-grained control – the type of a transaction
can be declared, for example – and extra functionality, such as the ability to create a
checkpoint (SAVEPOINT) in the middle of a transaction. Support for these extra features
may vary, and the best recommendation is to read the documentation for the DBMS
that you are currently using.
In the SQL standard, statements such as INSERT, UPDATE and SELECT are called transac-
tion-initiating statements, and if they follow a COMMIT or ROLLBACK, automatically
start a new transaction. We would recommend that this approach is avoided – it is usu-
ally clearer to have explicit START TRANSACTION commands where the DBMS provides
them.

Two-phase commit
We briefly discussed in chapter 2 of the first volume of this guide that a database may
be split into several resources. Although we will explore this subject in the next chapter
in more detail, one aspect of it directly affects transactions, and so needs to be intro-
duced here. Each resource in a distributed database will be manages by its own re-
source manager, each on a different machine.
If a transaction involves operations that need to be carried out on multiple resources, it
may involve more than one resource manager. If a database is split based on the de-
partments within an organisation, for example, all that is required is a transaction that

11
Chapter 2: Data preservation, security and database optimisation
modifies data from multiple departments. To keep the Atomicity requirement, the
DBMS must ensure that all resource managers perform their updates locally or that
none of them do. If one department updates its data and another does not, perhaps be-
cause that department’s computer crashes, then we are left with an inconsistent data-
base.
The presence of multiple resource managers distributed across a network adds a new
dimension to the problem of recovery. The DBMS has to implement global COMMIT and
ROLLBACK statements. When a global COMMIT is issued, the DBMS guarantees that all
the operations are committed, even in the case of a crash somewhere in the network. If
any single resource manager fails, then the global transaction must be rolled back. To
achieve this global task, a special system component, the co-ordinator, is needed.
To show how this is carried out, we can first look at the case where a transaction’s op-
erations have completed successfully, and the co-ordinator is issued with a global
COMMIT statement. The actions of the DBMS now are divided into two phases:
• Phase 1: the co-ordinator prepares each resource manager that is involved in the
transaction by sending a ‘get ready’ message. On receiving this message, each re-
source manager must force write in their log the description of all the operations it
has performed. Once this information is recorded on non-volatile storage, it will be
possible to commit or roll back the operations even if a crash occurs. If the force
writing process is completed successfully, the resource manager sends an OK to the
co-ordinator, otherwise it sends a NOT OK message.
• Phase 2: Once it has received responses from all the resource managers involved in
the transaction, the co-ordinator decides how to proceed. If all the answers were
OK, the co-ordinator will decide to commit; if even one response is NOT OK, it will
choose to roll back. The co-ordinator records its decision in its own log (so that, if
there is a crash, this decision will also be recovered) and then sends it to all the par-
ticipant resource managers. Even if a failure occurs, each resource manager is
guaranteed to execute the co-ordinator’s decision, because all the relevant infor-
mation has been written to permanent support.
The two-phase commit ensures that the atomicity of transactions is preserved across a
distributed database, with each resource manager first preparing and then committing
their share of the transaction. If an interruption occurs, the entire transaction is either
committed or rolled back as a whole.
There is an added risk, however, from this approach. If the co-ordinator itself fails
while the resource managers are waiting for its final decision, the separate databases
may remain in a locked state. Normally, this situation will be resolved when the co-
ordinator restarts, but the entire system becomes dependent on restoring this compo-
nent – something which acts against the aim of distributing the database in the first
place.

Concurrency control
Concurrency problems
Because a database is a shared resource, it must allow multiple users or programmes to
have concurrent access to data, that is, each must be able to access the database at the
same time. When we listed the five possible stages for transactions before a failure, we
allowed (in figure 2.4) five transactions to be accessing the database concurrently.
If we have many transactions occurring at once (that is, they are interleaved), there
should be no problem if each accesses disjoint parts of the database – if there is no data
in common between them. Problems occur when the same data is accessed by two or
more transactions at the same time.

12
Chapter 2: Data preservation, security and database optimisation
The problems caused by concurrent access to the same data can be classified into three
particular types:
• the inconsistent analysis problem;
• the lost update problem;
• the uncommitted dependency problem.
Inconsistent analysis The inconsistent analysis problem is caused by a transaction querying data that
another transaction is changing at the same time. To illustrate this, consider a whole-
saler selling party supplies. The wholesaler has three warehouses – A, B and C – that
stock balloons, and three fields of the database represent the current stock each carries
– BalloonsA, BalloonsB and BalloonsC.
Now, suppose there is a regular stock-checking transaction (Transaction 1) that queries
the number of balloons held by each warehouse, keeping a running total as it goes. On
its own, this would be an uncomplicated transaction, but suppose a second transaction
is executed that records that 200 balloons have been transported from warehouse A to
warehouse C. This information can be entered by first reducing the value of BalloonsA
by 200 and then increasing it in BalloonsC (Transaction 2). Clearly, the total number of
balloons stays the same, we have simply moved some from one place to another. Figure
2.6 illustrates what can happen.
Time Transaction 1 Transaction 2 Balloons
A B C
0 START TRANSACTION 200 200 600
1 RETRIEVE BalloonsA
[val=200, sum=200]
2 – START TRANSACTION
3 – UPDATE BalloonsA = BalloonsA - 200 0 200 600
4 – UPDATE BalloonsC = BalloonsC + 200 0 200 800
5 – COMMIT
6 RETRIEVE BalloonsB
[val=200, sum=400]
7 RETRIEVE BalloonsC 0 200 800
[val=800, sum=1200]
Figure 2.6. Two concurrent transactions resulting in an inconsistent analysis.

In the example above, there are 1,000 balloons distributed between the three ware-
houses, this is true both at the beginning and the end of the transactions. Even though,
in our example, Transaction 1 does nothing while Transaction 2 is running, and so only
operates on the database when it is both correct and consistent, it still produces an in-
correct total of 1,200 balloons.
This is because Transaction 2 changes the values of BalloonsA and BalloonsC between
Transaction 1 reading the one and the other. Although the state of the database has
been kept consistent, the transaction has not, and it has values from two different
states of the database.
Lost update The lost update problem arises when two transactions update the same data, but each
fails to take the action of the other into account. To return to our balloon stocks, con-
sider a transaction that checks the number currently available in a warehouse and, if
they are above a certain level, and some other database checks are satisfied, processes
an order for 200 and so reduces the stock level appropriately. Figure 2.7 shows what
this might look like if two transactions like this run concurrently.
Time Transaction 1 Transaction 2 BalloonsA
0 START TRANSACTION 300

13
Chapter 2: Data preservation, security and database optimisation
1 RETRIEVE BalloonsA
[val=300]
2 <other operations>
3 START TRANSACTION
4 RETRIEVE BalloonsA [val=300]
5 <other operations>
6 UPDATE BalloonsA = 300-200 100
7 UPDATE BalloonsA = 300-200 100
Figure 2.7. Two transactions each process orders for 200 balloons at the same time. Since there were
only 300 balloons available, these orders cannot be fulfilled.

In the example above, orders totalling 400 balloons have been processed even though
the warehouse only has 300 in stock. Furthermore, the database only shows the effect
of one of the two transactions. Since the update of Transaction 2 is based on data from
before Transaction 1 took place, the change Transaction 1 has made to BalloonsA is ig-
nored and overwritten.
Uncommitted dependency The uncommitted dependency problem occurs when as-yet-uncommitted changes
from one transaction are relied on by another transaction. This causes no problems if
the transaction is successfully committed, but if it is rolled back, then the values used
by the second transaction may never have been part of a consistent database state.
Figure 2.8 illustrates how this might affect the stock-taking transaction for our balloon
supplier when another transaction tries to withdraw stock and fails.

Time Transaction 1 Transaction 2 Balloons


A B C
0 START TRANSACTION 200 200 600
1 – START TRANSACTION
2 – UPDATE BalloonsA = BalloonsA - 200
3 RETRIEVE BalloonsA – 0 200 600
[val=0, sum=0]
4 – ROLLBACK 200 200 600
5 RETRIEVE BalloonsB
[val=200, sum=200]
6 RETRIEVE BalloonsC 200 200 600
[val=600, sum=800]
Figure 2.8. A read-only transaction (Transaction 1) using a value resulting from a transaction that is
later rolled back. The result is incorrect.

In the example above, the sum returned by Transaction 1 reflects a database state that
was never committed, and so is incorrect. The same problem arises if instead of merely
returning a value calculated from incorrect data, Transaction 1 stores it somewhere
else in the database. If Transaction 1 is wholly successful and Transaction 2 fails and is
rolled back, then the database will be inconsistent.
All these problems arise from concurrent access to the same resource. It is hard to
avoid them as long as full access to all data is provided all the time to several interac-
tions at the same time. To avoid the problems, we will need some sort of mechanism
that restricts data access at any point where having unrestricted access could introduce
inconsistencies.
Clearly, the simplest solution would be to permit one transaction only to be executed at
a time. This would be guaranteed to be free of concurrency problems, but would re-

14
Chapter 2: Data preservation, security and database optimisation
move an important part of what makes a DBMS useful. Nonetheless, there is one im-
portant aspect of this solution – it shows us that any method of carrying out a set of op-
erations that has the same results as this concurrency-free solution is, by definition,
free of concurrency problems. Such a method is called serialisable because the result is
indistinguishable from a serial, non-concurrent, ordering of the transactions.
Serialisable An interleaved execution of a set of transactions is serialisable if it produces the same
result as some serial execution of the same set of transactions, one at a time.
With this definition established, we can say that the interleaved execution of a set of
transactions is guaranteed to be correct if it is serialisable.
The way a set of transactions is executed is called a schedule. A schedule of a set of
transactions specifies the order in which the separate operations in the transactions
will be executed. As such, figures 2.6-2.8 represent schedules, but they are not serialis-
able, and thus give rise to concurrency issues.
There are many ways to try to achieve serialisable schedules, but by far the most com-
mon method is called locking.

Activity. Before we move on to discussing locking, consider the problem of se-


rialisation. What sorts of operations can be interleaved safely? What sorts will
necessarily interfere with each other? What would a method for ensuring seri-
alisability look like?

Locking
The locking mechanism provides a means for preventing multiple transactions from
accessing the same data in a way that might give rise to inconsistencies.
Before a transaction uses the data it refers to, it must acquire permission to use it. Per-
mission may be granted or refused depending on the type of access required and
whether the data is currently being used. If permission is granted, then the data will
have a lock placed on it that marks that it is being used and the type of use occurring.
Put more simply, a transaction can use data if it can acquire a lock on it.
There are two basic types of lock – Exclusive or write locks, and Shared or read locks
Exclusive lock An exclusive lock is required for any transaction that needs to modify a certain tuple.
Once a transaction has acquired an exclusive lock on a tuple, no other transaction can
access it – even for reading.
Shared lock A shared lock is required by any transaction that needs to retrieve data from a tuple,
but does not need to modify it. There can be any number of shared locks on a tuple at
any given time. If a transaction requests an exclusive lock, however, the request will be
refused if there are any shared locks already on the tuples involved.
The table in figure 2.9 gives a simple summary of how requests are treated given the
current lock state of the required data.
Current lock
Exclusive Shared None

Requested Exclusive ✗ ✗ ✓
lock Shared ✗ ✓ ✓
Figure 2.9. Table showing the requirements for acquiring a lock. An exclusive lock is only granted if no
other transaction is using the data, whilst a shared lock is granted provided no exclusive lock is al-
ready in place.

15
Chapter 2: Data preservation, security and database optimisation
It is enough in this guide to consider the tuple as the only lockable object, but, in his
chapter on concurrency, Date includes a section (‘Intent locking’) that discusses other
kinds of lockable object.
This locking mechanism is accompanied by a data access protocol that describes how it
is used. This is summarised below.
• A transaction that only needs to read the value of a tuple must first acquire a shared
lock on that tuple.
• A transaction that needs to modify or update a tuple must first acquire an exclusive
lock on that tuple.
• If a transaction is refused a lock on a tuple because another transaction has a lock
on it already, then it goes into a wait state until the lock is released. When more
than one transaction is waiting for a lock on the same tuple, a sub-module of the
concurrency control module called the scheduler decides on the order in which to
serve them. The scheduler should ensure that no transaction waits forever for its
lock to be granted.
• All locks are normally held until the transaction they were granted for is completed
– a COMMIT or ROLLBACK statement releases the lock.
The use of locking solves the various concurrency problems listed earlier. For example,
figure 2.10 shows how the uncommitted dependency problem shown in figure 2.8
would have been resolved.
Time Transaction 1 Transaction 2 Balloons
A B C
0 START TRANSACTION 200 200 600
<request shared lock
on BalloonsA>
<shared lock granted>
1 – START TRANSACTION
<request exclusive lock on BalloonsA>
<request denied>
2 RETRIEVE BalloonsA <wait>
[val=200, sum=200]
3 RETRIEVE BalloonsB <wait>
[val=200, sum=400]
4 RETRIEVE BalloonsC <wait>
[val=600, sum=1000]
5 COMMIT
<release Shared lock>
6 <exclusive lock granted> 0 200 600
UPDATE BalloonsA = BalloonsA - 200
7 ROLLBACK 200 200 600

Figure 2.10. Two transactions as in figure 2.8. This time, through locking, the second transaction is not
granted the ability to write to BalloonsA until after Transaction 1 has finished.

Activity. Construct similar tables to resolve the other two problems introduced
in figures 2.6 and 2.7. Does the use of locks like this fix these problems? Can you
see any other potential issues?

The data access protocol for locking allows us to resolve some problems, but gives rise
to some of its own. In the next section, we consider the problem of deadlocks and the
issues that arise from waiting for a lock to be released.

16
Chapter 2: Data preservation, security and database optimisation
Deadlocks
If we consider the lost update problem. The behaviour without locks was illustrated in
figure 2.7. Figure 2.11 shows the same transactions, only using locks.
Time Transaction 1 Transaction 2 BalloonsA
0 START TRANSACTION 300
<Request S lock on BalloonsA>
<S lock granted>
1 RETRIEVE BalloonsA [val=300]
2 <other operations>
3 START TRANSACTION
<Request S lock on BalloonsA>
<S lock granted>
4 <request X lock on BalloonsA> RETRIEVE BalloonsA [val=300]
<X lock denied>
5 <wait> <other operations>
6 <wait> <request X lock on BalloonsA>
<X lock denied>
7 <wait> <wait>
8 <wait> <wait>
Figure 2.11. Two transactions both acquire shared locks (S locks) on the same data. Later, each needs
an exclusive lock (X lock), but is denied the request because of the current S lock. Neither will release
its S lock till the new lock is granted, causing a deadlock.

The two transactions in this case each require, and obtain, a shared lock on BalloonsA.
Each transaction then requests an exclusive lock so that they may modify its value, but
the request is denied because, in each case, the other transaction still has a shared lock
on the data. Neither transaction will release its shared lock until it is granted the new
one (or, more commonly, until the end of the transaction). This results in a situation in
which each transaction is blocking the other from being able to progress, causing an
unending wait state. This situation is called deadlock.
A deadlock can also occur when each of two transactions holds two or more exclusive
locks in common, as shown in figure 2.12.
Time Transaction 1 Transaction 2
0 <some operations> <some operations>
1 <request X lock on r1>
<X lock granted>
<operation on r1>
2 <request X lock on r2>
<X lock granted>
<operation on r2>
3 <request X lock on r2>
<X lock denied>
4 <wait> <request X lock on r1>
<X lock denied>
5 <wait> <wait>
Figure 2.12. A deadlock caused by one transaction operating on r1 and then r2 and another r2 and then
r1. Each has a lock that the other needs, but neither will be first to release it.

In summary, with the help of shared and exclusive locks and the data access protocol,
we can solve many of the problems of concurrent transactions, but only by introducing
a new problem in the form of deadlocks.
Although it is possible to have a deadlock involving more than two transactions, this
case is rare in practice.

17
Chapter 2: Data preservation, security and database optimisation

Activity. Try to construct a situation in which three transactions result in a


deadlock.

Since a deadlock will never break on its own, the system must identify such situations
and resolve them. The most common way to detect deadlocks involves each system
maintaining a directed graph that represents which transaction is waiting for which
other ones to complete.

Figure 2.13. Example of a wait-for graph.

Figure 2.13 shows a simple wait-for graph. Transaction A depends on B and C to com-
plete, C is waiting for D which in turn is waiting for B. In this case, the sequence B then
D then C then A will complete without any need for intervention.
Figure 2.14 shows a larger wait-for graph. In this case, F is waiting for C, but is one of
the two transactions that C is waiting for, causing a deadlock. The same is true for
{BED}.

Figure 2.14. A wait-for graph showing two deadlocks (indicated by cyclical arrows)

By checking for cycles in the wait-for graph at regular intervals, the system can identify
and resolve deadlocks. Once a deadlock is identified, the system terminates one of the
transactions involved by rolling it back. The terminated transaction is called the victim.
Rolling back the victim results in it releasing the locks that it holds, resolving the dead-
lock. Usually, the victim is automatically restarted after the deadlock has cleared. How
the victim is chosen is outside the scope of this guide.
Despite the risks posed by deadlocks and the extra complications of dealing with them,
the locking mechanism allows a DBMS to extend the guarantees of transaction execu-
tion to all concurrent transaction execution.

Serialisability
The approaches described in the previous section is a way to ensure that a schedule is
serialisable, and thus correct.
Time: t1 t2 t3 t4 t5 t6 t7 t8 t9
Transaction 1 op1-1 op1-2 op1-3 op1-4
Transaction 2 op2-1 op2-2 op2-3
Transaction 3 op3-1 op3-2
Figure 2.15. Schedule showing operations of three transactions executed serially: first Transaction 1,
then Transaction 3 then Transaction 2.

18
Chapter 2: Data preservation, security and database optimisation
Time: t1 t2 t3 t4 t5 t6 t7 t8 t9
Transaction 1 op1-1 op1-2 op1-3 op1-4
Transaction 2 op2-1 op2-2 op2-3
Transaction 3 op3-1 op3-2
Figure 2.16. Three interleaved transactions. The important question: is this serialisable?

Figures 2.15 and 2.16 show a serial and an interleaved schedule for the same three
transactions. It should be clear now that the outcome of the two will be the same if:
• the operations work on completely different data, making locking irrelevant; or
• all operations are SELECT operations, since none of the data will be changed by the
concurrent transactions – this is why shared locks do not exclude other shared
locks from being granted.
If one item writes a data item and the other reads it, the order does matter. An exclu-
sive lock granted until the end of a transaction guarantees that the result is serialisable.
For example, if op1-1 reads the same tuple that op1-3 writes, then requiring a lock on
that triple for the remainder of Transaction 1 and Transaction 2 will guarantee that
that the schedule shown in figure 2.16 is equivalent to running Transaction 1 first and
then Transaction 2 (since that is the order in which the locks will be requested and
granted, if these are the only transactions running). A different schedule might be
equivalent to running Transaction 2 first, but will still guarantee serialisability.
In fact, a further definition is still needed to be sure that all possible interleaved sched-
ules are correct. We have assumed certain restrictions on how locks are requested and
released that we should now make explicit, since they are the final piece required to
guarantee correctness of a schedule. These restrictions are codified as the two-phase
locking protocol.
2-phase locking protocol The two-phase locking protocol requires that:
• a transaction must acquire a lock on any object before accessing it; and
• after releasing a lock, a transaction must not attempt to acquire other locks.
This is called two-phase locking because these restrictions mean that a transaction can
be divided into two phases. During the first phase, as each operation is carried out,
locks are either acquired or upgraded (from shared to exclusive). The second phase oc-
curs only once all the locks that will be needed have been acquired, at which point locks
may be released.
In almost all RDBMS implementations, the second phase is entered only when all a
transactions operations have carried out – when the COMMIT or ROLLBACK operation
is reached – at which point all the locks acquired by the transaction can be released.
This stricter form of the two-phase locking protocol is called strong strict two-phase
locking (sometimes shortened to SS2PL).
It is important to remember that ensuring that a set of transactions are serialisable is
only a way of guaranteeing the correctness of a schedule, that anomalies in the data-
base will be avoided. What it does not do is avoid deadlocks.

Data security
Since a database is a shared resource where all the relevant information of an institu-
tion may be stored, users are usually only allowed to see or modify the parts of it that
apply to them.
To use our recurring example, in a university’s database, students are likely to be able
to see information about the courses offered, about timetables and about themselves,
but they are unlikely to be able to modify any of it or see information about other stu-

19

You might also like