Serializability


In concurrency control of databases, transaction processing, and various transactional applications, both centralized and distributed, a transaction schedule is serializable if its outcome is equal to the outcome of its transactions executed serially, i.e. without overlapping in time. Transactions are normally executed concurrently, since this is the most efficient way. Serializability is the major correctness criterion for concurrent transactions' executions. It is considered the highest level of isolation between transactions, and plays an essential role in concurrency control. As such it is supported in all general purpose database systems. Strong strict two-phase locking is a popular serializability mechanism utilized in most of the database systems since their early days in the 1970s.
Serializability theory provides the formal framework to reason about and analyze serializability and its techniques. Though it is mathematical in nature, its fundamentals are informally introduced below.

Correctness

Serializability

Serializability is used to keep the data in the data item in a consistent state. Serializability is a property of a transaction schedule. It relates to the isolation property of a database transaction.
Schedules that are not serializable are likely to generate erroneous outcomes. Well known examples are with transactions that debit and credit accounts with money: If the related schedules are not serializable, then the total sum of money may not be preserved. Money could disappear, or be generated from nowhere. This and violations of possibly needed other invariant preservations are caused by one transaction writing, and "stepping on" and erasing what has been written by another transaction before it has become permanent in the database. It does not happen if serializability is maintained.
If any specific order between some transactions is requested by an application, then it is enforced independently of the underlying serializability mechanisms. These mechanisms are typically indifferent to any specific order, and generate some unpredictable partial order that is typically compatible with multiple serial orders of these transactions. This partial order results from the scheduling orders of concurrent transactions' data access operations, which depend on many factors.
A major characteristic of a database transaction is atomicity, which means that it either commits, i.e., all its operations' results take effect in the database, or aborts, all its operations' results do not have any effect on the database. In all real systems transactions can abort for many reasons, and serializability by itself is not sufficient for correctness. Schedules also need to possess the recoverability property. Recoverability means that committed transactions have not read data written by aborted transactions. While serializability is currently compromised on purpose in many applications for better performance, compromising recoverability would quickly violate the database's integrity, as well as that of transactions' results external to the database. A schedule with the recoverability property "recovers" from aborts by itself, i.e., aborts do not harm the integrity of its committed transactions and resulting database. This is false without recoverability, where the likely integrity violations need special, typically manual, corrective actions in the database.
Implementing recoverability in its general form may result in cascading aborts: Aborting one transaction may result in a need to abort a second transaction, and then a third, and so on. This results in a waste of already partially executed transactions, and may result also in a performance penalty. Avoiding cascading aborts is a special case of recoverability that exactly prevents such phenomena. Often in practice a special case of ACA is utilized: Strictness. Strictness allows efficient database recovery from failure.
Note that the recoverability property is needed even if no database failure occurs and no database recovery from failure is needed. It is, rather, needed to correctly automatically handle aborts, which may be unrelated to database failure and recovery from failure.

Relaxing serializability

In many applications, unlike with finances, absolute correctness is not needed. For example, when retrieving a list of products according to specification, in most cases it does not matter much if a product, whose data was updated a short time ago, does not appear in the list, even if it meets the specification. It will typically appear in such a list when tried again a short time later. Commercial databases provide concurrency control with a whole range of isolation levels which are in fact serializability violations in order to achieve higher performance. Higher performance means better transaction execution rate and shorter average transaction response time. Snapshot isolation is an example of a popular, widely utilized efficient relaxed serializability method with many characteristics of full serializability, but still short of some, and unfit in many situations.
Another common reason nowadays for distributed serializability relaxation is the requirement of availability of internet products and services. This requirement is typically answered by large-scale data replication. The straightforward solution for synchronizing replicas' updates of the same database object is including all these updates in a single atomic distributed transaction. However, with many replicas such a transaction is very large, and may span enough of a number of several computers and networks that some of them are likely to be unavailable. Thus such a transaction is likely to end with abort and miss its purpose.
Consequently, Optimistic replication is often utilized, while serializability is relaxed and compromised for eventual consistency. Again, in this case, relaxation is done only for applications that are not expected to be harmed by this technique.
Classes of schedules defined by relaxed serializability properties either contain the serializability class, or are incomparable with it.

View and conflict serializability

Mechanisms that enforce serializability need to execute in real time, or almost in real time, while transactions are running at high rates. In order to meet this requirement, special cases of serializability, sufficient conditions for serializability which can be enforced effectively, are utilized.
Two major types of serializability exist: view-serializability, and conflict-serializability. View-serializability matches the general definition of serializability given above. Conflict-serializability is a broad special case, i.e., any schedule that is conflict-serializable is also view-serializable, but not necessarily the opposite. Conflict-serializability is widely utilized because it is easier to determine and covers a substantial portion of the view-serializable schedules. Determining view-serializability of a schedule is an NP-complete problem.
Operations upon data are read or write. Two operations are conflicting if they are of different transactions, upon the same datum, and at least one of them is write. Each such pair of conflicting operations has a conflict type: it is either a read–write, or write–read, or a write–write conflict. The transaction of the second operation in the pair is said to be in conflict with the transaction of the first operation. A more general definition of conflicting operations requires that they are noncommutative. Each such operation needs to be atomic by itself in order to be considered an operation for a commutativity check. For example, read–read operations are commutative and thus read–read is not a conflict. Another more complex example: the operations increment and decrement of a counter are both write operations, but do not need to be considered conflicting since they are commutative. Only precedence in pairs of conflicting operations is important when checking equivalence to a serial schedule, since different schedules consisting of the same transactions can be transformed from one to another by changing orders between different transactions' operations, and since changing orders of commutative operations does not change an overall operation sequence result, i.e., a schedule outcome. This means that if a schedule can be transformed to any serial schedule without changing orders of conflicting operations, then the outcome of both schedules is the same, and the schedule is conflict-serializable by definition.
Conflicts are the reason for blocking transactions and delays, or for aborting transactions due to serializability violation prevention. Both possibilities reduce performance. Thus reducing the number of conflicts, e.g., by commutativity, is a way to increase performance.
A transaction can issue/request a conflicting operation and be in conflict with another transaction while its conflicting operation is delayed and not executed. Only executed conflicting operations are relevant to conflict serializability.

Enforcing conflict serializability

Testing conflict serializability

Schedule compliance with conflict serializability can be tested with the precedence graph for committed transactions of the schedule. It is the directed graph representing precedence of transactions in the schedule, as reflected by precedence of conflicting operations in the transactions.
The following observation is a key characterization of conflict serializability:
Cycles of committed transactions can be prevented by aborting an undecided transaction on each cycle in the precedence graph of all the transactions, which can otherwise turn into a cycle of committed transactions. One transaction aborted per cycle is both required and sufficient in number to break and eliminate the cycle. The probability of cycle generation is typically low, but, nevertheless, such a situation is carefully handled, typically with a considerable amount of overhead, since correctness is involved. Transactions aborted due to serializability violation prevention are restarted and executed again immediately.
Serializability-enforcing mechanisms typically do not maintain a precedence graph as a data structure, but rather prevent or break cycles implicitly.

Common mechanism — SS2PL

Strong strict two-phase locking is a common mechanism utilized in database systems since their early days in the 1970s to enforce both conflict serializability and strictness of a schedule. Under this mechanism, each datum is locked by a transaction before its accessing it : the item is marked by and associated with a lock of a certain type depending on the operation being performed. As a result, access by another transaction may be blocked, typically upon a conflict, depending on lock type and the other transaction's access operation type. Employing an SS2PL mechanism means that all locks on data on behalf of a transaction are released only after the transaction has ended.
SS2PL is the name of the resulting schedule property as well, which is also called rigorousness. SS2PL is a special case of Two-phase locking
Mutual blocking between transactions results in a deadlock, where execution of these transactions is stalled and no completion can be reached. Thus deadlocks need to be resolved to complete these transactions' execution and release related computing resources. A deadlock is a reflection of a potential cycle in the precedence graph that would occur without the blocking when conflicts are materialized. A deadlock is resolved by aborting a transaction involved with such a potential cycle and breaking the cycle. It is often detected using a wait-for graph, which indicates which transaction is "waiting for" the release of one of more locks by which other transaction or transactions, and a cycle in this graph means a deadlock. Aborting one transaction per cycle is sufficient to break the cycle. Transactions aborted due to deadlock resolution are restarted and executed again immediately.

Other enforcing techniques

Other known mechanisms include:
The above serializability techniques in their general form do not provide recoverability. Special enhancements are needed for adding recoverability.

Optimistic versus pessimistic techniques

Concurrency control techniques are of three major types:
  1. Pessimistic: In Pessimistic concurrency control, a transaction blocks the data access operations of other transactions upon conflicts, and conflicts are non-materialized until blocking is removed. This is done to ensure that operations that may violate serializability do not occur.
  2. Optimistic: In Optimistic concurrency control, the data access operations of other transactions are not blocked upon conflicts, and conflicts are immediately materialized. When the transaction reaches the ready state, i.e., its running state has been completed, possible serializability violation by the transaction's operations is checked: if violation has occurred, the transaction is typically aborted. Otherwise, it is committed.
  3. Semi-optimistic: Mechanisms that mix blocking in certain situations with not blocking in other situations and employ both materialized and non-materialized conflicts
The main differences between the technique types is the conflict types that are generated by them. A pessimistic method blocks a transaction operation upon conflict and generates a non-materialized conflict, while an optimistic method does not block and generates a materialized conflict. A semi-optimistic method generates both conflict types. Both conflict types are generated by the chronological orders in which transaction operations are invoked, independently of the type of conflict. A cycle of committed transactions in the precedence graph represents a serializability violation, and should be avoided for maintaining serializability. A cycle of conflicts in the wait-for graph represents a deadlock situation, which should be resolved by breaking the cycle. Both cycle types result from conflicts and should be broken. Under any technique type, conflicts should be detected and considered, with similar overhead for both materialized and non-materialized conflicts. In a blocking method, typically a context switching occurs upon conflict, with incurred overhead. Otherwise, blocked transactions' related computing resources remain idle, unutilized, which may be a worse alternative. When conflicts do not occur frequently, optimistic methods typically have an advantage. With different transaction loads one technique type may provide better performance than the other.
Unless schedule classes are inherently blocking, they can also be implemented using optimistic techniques.

Serializable multi-version concurrency control

Multi-version concurrency control is a common way today to increase concurrency and performance by generating a new version of a database object each time the object is written and allowing transactions' read operations of several last relevant versions, depending on scheduling method. MVCC can be combined with all the serializability techniques listed above. It is utilized in most general-purpose DBMS products.
MVCC is especially popular nowadays through the relaxed serializability method Snapshot isolation which provides better performance than most known serializability mechanisms. SerializableSI, which is an efficient enhancement of SI to make it serializable, is intended to provide an efficient serializable solution. SerializableSI has been analyzed via a general theory of MVCC

Distributed serializability

Overview

Distributed serializability is the serializability of a schedule of a transactional distributed system. Such a system is characterized by distributed transactions, i.e., transactions that span computer processes and possibly network nodes. A distributed transaction comprises more than one of several local sub-transactions that each has states as described above for a database transaction. A local sub-transaction comprises a single process, or more processes that typically fail together. Distributed transactions imply a need for an atomic commit protocol to reach consensus among its local sub-transactions on whether to commit or abort. Such protocols can vary from a simple handshake among processes that fail together to more sophisticated protocols, like two-phase commit, to handle more complicated cases of failure. Distributed serializability is a major goal of distributed concurrency control for correctness. With the proliferation of the Internet, cloud computing, grid computing, and small, portable, powerful computing devices the need for effective distributed serializability techniques to ensure correctness in and among distributed applications seems to increase.
Distributed serializability is achieved by implementing distributed versions of the known centralized techniques. Typically, all such distributed versions require utilizing conflict information that is not generated locally, but rather in different processes, and remote locations. Thus information distribution is needed. When the distributed system is of a relatively small scale and message delays across the system are small, the centralized concurrency control methods can be used unchanged while certain processes or nodes in the system manage the related algorithms. However, in a large-scale system, due to the distribution of such information, a substantial performance penalty is typically incurred, even when distributed versions of the methods are used, primarily due to computer and communication latency. Also, when such information is distributed, related techniques typically do not scale well. A well-known example with respect to scalability problems is a distributed lock manager, which distributes lock information across the distributed system to implement locking techniques.