local atomicity properties: modular concurrency control

35
Local Atomicity Properties: Modular Concurrency Control for Abstract Data Types WILLIAM E. WEIHL MIT Laboratory for Computer Science Atomic actions (or transactions) are useful for coping with concurrency and failures. One way of ensuring atomicity of actions is to implement applications in terms of atomic data types: abstract data types whose objects ensure serializability and recoverability of actions using them. Many atomic types can be implemented to provide high levels of concurrency by taking advantage of algebraic properties of the type’s operations, for example, that certain operations commute. In this paper we analyze the level of concurrency permitted by an atomic type. We introduce several local constraints on individual objects that suffice to ensure global atomicity of actions; we call these constraints local atomicity properties. We present three local atomicity properties, each of which is optimal: no strictly weaker local constraint on objects suffices to ensure global atomicity for actions. Thus, the local atomicity properties define precise limits on the amount of concurrency that can be permitted by an atomic type. Categories and Subject Descriptors: C.2.4 [Computer-Communication Networks]: Distributed Systems--distributed applications, distributed databases; D.1.3 [Programming Techniques]: Con- current Programming; D.2.1 [Software Engineering]: Requirements/Specifications-methodol- ogies; D.4.1 [Operating Systems]: Process Management-concurrency, synchronization; D.4.5 [Op- erating Systems]: Reliability-checkpoint/restart, fault-tolerance, uerificution; H.2.4 [Database Management]: Systems-distributed systems, transaction processing General Terms: Reliability, Theory Additional Key Words and Phrases: Abstract data types, atomic actions, atomic types, concurrency, transactions 1. INTRODUCTION There are many applications in which the manipulation and preservation of long- lived, on-line data is of primary importance. Examples of such applications are banking systems, airline reservation systems, office automation systems, database The material in this paper is based on the author’s Ph.D. dissertation. A preliminary version of some of this material appeared in a paper in the Second Symposium on Principles of Distributed Computing (Aug. 1983). This work was supported in part by the Advanced Projects Research Agency of the Department of Defense, monitored by the Office of Naval Research under contract N00014-83-K- 1025, and in part by the National Science Foundation under grant DCR-8510014. Author’s address: MIT Laboratory for Computer Science, 545 Technology Square, Cambridge, MA 02139. Permission to copy without fee all or part of this material is granted provided that the copies are not made or distributed for direct commercial advantage, the ACM copyright notice and the title of the publication and its date appear, and notice is given that copying is by permission of the Association for Computing Machinery. To copy otherwise, or to republish, requires a fee and/or specific permission. 0 1989 ACM 0764-0925/89/0400-0249 $01.50 ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989, Pages 249-282.

Upload: others

Post on 28-May-2022

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties: Modular Concurrency Control for Abstract Data Types WILLIAM E. WEIHL MIT Laboratory for Computer Science

Atomic actions (or transactions) are useful for coping with concurrency and failures. One way of ensuring atomicity of actions is to implement applications in terms of atomic data types: abstract data types whose objects ensure serializability and recoverability of actions using them. Many atomic types can be implemented to provide high levels of concurrency by taking advantage of algebraic properties of the type’s operations, for example, that certain operations commute. In this paper we analyze the level of concurrency permitted by an atomic type. We introduce several local constraints on individual objects that suffice to ensure global atomicity of actions; we call these constraints local atomicity properties. We present three local atomicity properties, each of which is optimal: no strictly weaker local constraint on objects suffices to ensure global atomicity for actions. Thus, the local atomicity properties define precise limits on the amount of concurrency that can be permitted by an atomic type.

Categories and Subject Descriptors: C.2.4 [Computer-Communication Networks]: Distributed Systems--distributed applications, distributed databases; D.1.3 [Programming Techniques]: Con- current Programming; D.2.1 [Software Engineering]: Requirements/Specifications-methodol- ogies; D.4.1 [Operating Systems]: Process Management-concurrency, synchronization; D.4.5 [Op- erating Systems]: Reliability-checkpoint/restart, fault-tolerance, uerificution; H.2.4 [Database Management]: Systems-distributed systems, transaction processing

General Terms: Reliability, Theory

Additional Key Words and Phrases: Abstract data types, atomic actions, atomic types, concurrency, transactions

1. INTRODUCTION

There are many applications in which the manipulation and preservation of long- lived, on-line data is of primary importance. Examples of such applications are banking systems, airline reservation systems, office automation systems, database

The material in this paper is based on the author’s Ph.D. dissertation. A preliminary version of some of this material appeared in a paper in the Second Symposium on Principles of Distributed Computing (Aug. 1983). This work was supported in part by the Advanced Projects Research Agency of the Department of Defense, monitored by the Office of Naval Research under contract N00014-83-K- 1025, and in part by the National Science Foundation under grant DCR-8510014. Author’s address: MIT Laboratory for Computer Science, 545 Technology Square, Cambridge, MA 02139. Permission to copy without fee all or part of this material is granted provided that the copies are not made or distributed for direct commercial advantage, the ACM copyright notice and the title of the publication and its date appear, and notice is given that copying is by permission of the Association for Computing Machinery. To copy otherwise, or to republish, requires a fee and/or specific permission. 0 1989 ACM 0764-0925/89/0400-0249 $01.50

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989, Pages 249-282.

Page 2: Local Atomicity Properties: Modular Concurrency Control

250 * William E. Weihl

systems, and various components of operating systems. A major issue in such systems is preserving the consistency of data in the presence of concurrency and hardware failures. In this paper we consider how to define data objects that help provide this consistency. We focus on how to specify such objects, not on how to implement them, and consider questions such as how much concurrency an object can permit while still ensuring consistency. (A discussion of implementation issues can be found in, e.g., [42] and [46].)

To support consistency it is helpful to make the activities that use and manipulate data atomic. Atomic activities are often referred to as actions or transactions; they were first identified in work on databases [9, 10, 121. Atomic transactions are characterized informally by two properties: serializability and recoverability. Serializability means that the concurrent execution of a group of transactions is equivalent to some serial execution of the same transactions. Recoverability means that each transaction appears to be all or nothing: either it executes successfully to completion (in which case we say that it commits), or it has no effect on data shared with other transactions (in which case we say that it aborts).

Atomicity simplifies the problem of maintaining consistency by decreasing the number of cases that need to be considered. Since aborted transactions have no effect and every concurrent execution is equivalent to some serial execution, consistency is ensured as long as every possible serial execution of committed transactions maintains consistency. Even though transactions execute concur- rently, concurrency can be ignored when checking for consistency.

In this paper we explore an approach in which atomicity is achieved through the shared data objects, which must be implemented in such a way that the transactions using them appear to be atomic. Objects that provide appropriate synchronization and recovery are called atomic objects; atomicity is guaranteed only when all objects shared by transactions are atomic objects. By encapsulating the synchronization and recovery needed to support atomicity in the implemen- tations of the shared objects, we can enhance modularity; in addition, by using information about the specifications of the shared objects, we can increase concurrency among transactions. (Examples illustrating how specifications can be used to enhance concurrency will be given in the body of this paper; further examples, including detailed algorithms, can be found in a number of papers, including [17]-[19], [37], [42], and [44]-[46].)

Atomic objects are encapsulated within atomic abstract data types. An abstract data type consists of a set of objects and a set of primitive operations; the primitive operations are the only means of accessing and manipulating the objects [ZS]. In addition, the operations of an atomic type ensure serializability and recoverability of transactions using the type.

In this paper we investigate the semantics of atomic types. We address two fundamental questions. First, what is an atomic type? We need a precise characterization of the behavior of atomic types, For example, we need to know how much concurrency can be allowed by an atomic type. Second, how do we specify an atomic type? For example, what aspects of an atomic type’s behavior must appear in its specification, and how should the specification be structured? ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989

Page 3: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties 251

To answer these questions, we must generalize existing work (e.g., [33]) on concurrency control (or serializability) in three ways:

(1) Our definition of atomicity is data dependent: it is based on an explicit specification of the desired behavior for the data objects used by transactions. This is crucial in achieving the concurrency required by applications.

(2) Our definition of atomicity is integrated: we treat both serializability and recoverability. This facilitates the description and verification of implemen- tations of atomic objects, which necessarily must cope with both.

(3) We focus on modularity issues: we identify local properties of individual objects that suffice to ensure atomicity of transactions.

Most work on concurrency control addresses at most one of these issues. We know of none that addresses all three; indeed, our focus on modularity issues appears to be unique in the literature on concurrency control. For example, a few recent papers [3, 6, 211 address the problem of extending concurrency control protocols to cope with arbitrary user-defined operations. However, they focus exclusively on locking protocols and do not consider modularity issues. In addition, they ignore recovery. Some work (e.g., [ 151 and [30]) considers recover- ability in addition to serializability. However, this work does not address modu- larity issues, nor does it consider using specifications of objects to enhance concurrency.

The local properties of objects defined in this paper characterize the concur- rency that can be permitted by an object, given the information available to it about the rest of the system. We explore three local properties, each of which is optimal: no strictly weaker local property suffices to ensure atomicity. The three properties characterize the behavior of three common classes of protocols: dy- namic protocols, such as two-phase locking (e.g., [12]), in which the serialization order of transactions is determined by the order in which they access objects; multiversion timestamp-based protocols, such as Reed’s protocol [36], in which the serialization order of transactions is based on a predetermined total order; and hybrid protocols (e.g., [43]), which use a combination of these techniques. These local properties provide answers to the question of how much concurrency can be permitted by an atomic object.

We also suggest a specification framework in which an object’s specification is divided into two parts: the serial specification, which describes the object’s permissible behavior in the absence of concurrency and failures, and the behav- ioral specification, which describes how the object responds to concurrency and failures. This framework permits the programmer of an individual transaction to ignore how atomicity is achieved. To reason about whether an individual trans- action preserves consistency, one needs only the serial specification of each object used by the transaction, and the knowledge that transactions are atomic; one need not know how objects cooperate to ensure atomicity. In addition, our specification framework supports an approach that permits the behavioral spec- ification of an object to be derived systematically from its serial specification. In other words, we reduce the problem of specifying an object’s behavior to the simpler problem of specifying how it should behave in the absence of concurrency and failures.

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 4: Local Atomicity Properties: Modular Concurrency Control

252 - William E. Weihl

An important feature of our specification framework is that it permits non- deterministic operations (e.g., a choose operation on a set) to be specified. Other papers [3, 6, 21, 371 restrict the operations specified by the user to be functions. It has long been recognized in the literature on data abstraction that nondeterministic specifications are useful for avoiding over-specifying ab- stractions. As discussed in [27] and [46], nondeterminism also plays an im- portant role in achieving adequate concurrency and availability while ensuring atomicity.

We note that we will not present particular specification languages for atomic types; rather, we focus on the underlying formal models of specifications and on identifying desirable semantic properties of atomic types.

The remainder of this paper is organized as follows: In Section 2 we present our formal model of computations and specifications. Then, in Section 3 we use the model to define atomicity of transactions. Next, in Section 4 we define three “local atomicity properties:” properties of individual objects that ensure atomicity of transactions. Finally, we conclude with a summary of our results and some suggestions for further work.

2. SYSTEM MODEL

We use a simple event-based model to describe systems. For our purposes, a system is composed of transactions and objects. Each component of a system has a specification that describes its acceptable behavior. A specification of a com- ponent serves as a contract between a user of the component and its implementor: the user relies only on the properties guaranteed by the specification, and the implementor agrees to ensure those properties. Specifications provide an impor- tant form of abstraction, since a component’s user only needs to know what is described in the component’s specification, and can ignore implementation details.

The specification of a component is described in terms of the events that occur at its interface with other components. An implementation might be described in terms of lower level, more detailed events. In this paper our focus is on the semantic constraints on objects necessary to ensure atomicity of transactions. It is easiest to analyze these constraints at an object’s interface with other compo- nents, rather than in terms of the more detailed behavior of an implementation of an object. Thus, in this paper we do not discuss in detail how the components of a system can be implemented to satisfy their specifications.

We view each transaction as a sequential process. Thus, we do not permit concurrency within a transaction. We expect concurrency within a transaction to be obtained through the use of nested transactions, as in [26] and [32]. However, in the formal analysis in this paper we do not permit transactions to be nested. (There is a kind of nesting in our model, namely, the nesting of levels of abstraction. This is similar to the nesting considered in [3].) In recent work we have begun to extend the work reported here to include nested transactions. A description of our formal model for nested transactions can be found in [31]; applications of the model to locking and timestamp-based concurrency control algorithms can be found in [2] and [13]. ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 5: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties 253

We begin in Section 2.1 by describing the components of a system and by defining computations. Then, in Section 2.2 we describe how we model specifi- cations of objects, and how the specifications of the components of a system constrain the possible behavior of the system as a whole.

2.1 Computations and Observations

A system is composed of transactions and objects. Transactions correspond roughly to processes or threads of control: they are the active entities in the system and perform tasks for users. Objects contain the state of the system: they provide operations by which transactions can examine and modify the system state, and constitute the sole path by which transactions can pass information among themselves. We will typically use the symbols a, b, and c (possibly subscripted) for transactions, and the symbols X, y, and z (possibly subscripted) for objects.

To define atomicity, the events in which we are interested are events that occur at the interface between objects and transactions. Internal events of components-that is, implementation details-can be ignored. For most of this paper, we assume that an event is either the invocation of an operation on an object by a transaction, the termination of an invocation, the commit (successful completion) of a transaction at an object, or the abort (unsuccessful completion) of a transaction at an object. (In later sections we introduce some additional events that are needed to describe the operation of certain kinds of protocols.) A note on terminology: we use the word termination to mean the end of the execution of a single operation, and the word completion to mean the end of the execution of an entire transaction. Each event identifies the transaction and the object that participate in it. If a transaction (object) participates in an event, we say that the event involves the transaction (object).

For example, suppose x is an object that is intended to behave as a set of integers, with operations to insert an integer in x, to delete an integer, and to check for membership. If a is a transaction, example events include the following:

-a invokes insert on x with argument 3 (written (insert(3), x, a)); -an invocation of an operation by a on x terminates with result “ok” (written

(ok, x, a>); -a invokes member on x with argument 7 (written (member(7), x, a)); -an invocation of an operation by a on x terminates with result “true” (written

(true, x, a>); -a commits at x (written (commit, x, a)); and -a aborts at x (written (abort, x, a)).

Notice that an invocation event includes information about the arguments of the operation; similarly, a termination event includes information about the results.

A computation is most properly viewed as a partial order of events (cf. [24]). For our purposes, however, it suffices to restrict our attention to the observable behavior of a system. We model an observation of a system as a finite sequence of events. For example, if a and b are transactions, the following event sequence

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 6: Local Atomicity Properties: Modular Concurrency Control

254 - William E. Weihl

might be an observation of a system containing a set object x:

(insert(3), x, a) (ok, x, a) (member(3), x, b) (commit, x, a) (true, x, b) (commit, x, b)

If h is an event sequence and X is a set of objects, we define h 1 X (“h restricted to X”) to be the subsequence of h consisting of all events involving objects in X. We define h 1 A similarly for a set of transactions A. If 3c is an object and a is a transaction, we write h 1 x for h 1 (x), and h 1 a for h 1 (a). We also define committed(h) to be the set of transactions that commit in h, and aborted(h) to be the set of transactions that abort in h. Finally, we define completed(h) to be the set of transactions that complete (commit or abort) in h; that is, com- pleted(h) = committed(h) U aborted(h).

We use the following notation for sequences: the symbol “.” denotes con- catenation of sequences, and the symbol “‘1” denotes the empty sequence.

We include here two technical lemmas. The first lemma asserts the commu- tativity of the restriction operators:

LEMMA 1. Suppose X and Y are sets of objects, and A and B are sets of transactions. Then,

(1) (hIX)IY=(hIY)IX=hI(XnY), (2) (hIA)IB=(hIB)IA=h.l(AnB),und

(3) (hIX)lA = (hIA) IX. The second lemma asserts that restriction distributes over concatenation:

LEMMA 2. Suppose S is a set of objects, and h and k are event sequences. Then,

(h . k) IS = (his) . (his).

The same property holds when S is a set of transactions.

Not all event sequences make sense as observations: a transaction is intended to act as a sequential process. In other words, a transaction executes a sequence of operations, possibly involving several objects. At some point it may abort, or if it completes all its operations, it may commit. Thus, we restrict our attention to event sequences h satisfying the following conditions:

-A transaction must wait until one invocation terminates before invoking another operation. More precisely, let op-euents(h) be the subsequence of h consisting of all invocation and termination events; then op-events (h 1 a) must consist of an alternating sequence of invocation and termination events, beginning with an invocation event. In addition, an invocation event and the immediately succeeding termination event must involve the same object.

-No transaction both commits and aborts in h (at the same or different objects); that is, committed(h) n aborted(h) = 0.

-A transaction cannot commit if it is waiting for an invocation to terminate, and a transaction cannot invoke any operations after it commits. More

AC-M Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 7: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties - 255

precisely, if a E committed(h), then h ( a consists of op-euents(h 1 a) followed by some number of commit events; in addition, op-euents(h ( a) must end in a termination event.

Such “well-formed” event sequences will be called histories; in the remainder of this paper, we are concerned only with histories, not with arbitrary event sequences.

Histories are intended to model the typical use of atomic transactions in existing systems. A transaction executes by invoking operations on objects, receiving results when the operations terminate. Since we disallow concurrency within a transaction, a transaction is permitted at most one pending invocation at any time. After successful termination of all invocations, a transaction can commit at one or more objects.

,

We make very few restrictions on aborted transactions; for example, a trans- action can continue to invoke operations after it has aborted. We have two reasons for avoiding additional restrictions. First, we have no need for them in our analysis. Second, and more important, additional restrictions might be too strong to model systems with orphans [20, 291, and we would like our results to be as generally applicable as possible.

A transaction is not allowed to commit at some objects and abort at others; this requirement, called atomic commitment, can be implemented using a com- mitment protocol such as two-phase commit [14,25] or three-phase commit [40].

In this paper we are interested primarily in those event sequences that are complete in the following sense: an event sequence h is complete if every transaction either completes at every object or does nothing at the object; that is, for all a and x, either a E completed(h ] x), or h ] a ] x = A. By focusing on complete sequences, we are able to analyze the interactions among objects without burdening the analysis with details of how implementations operate step-by-step in an on-line manner. Given the local properties developed later in this paper, we can then turn our attention to designing on-line implementations of objects that ensure those properties. The precise description and verification of such implementations can be found in [ 181, [ 191, [44], and [45].

2.2 Specifications

The behavior of a system is determined by the behaviors of its components and the interconnections among the components. The specification of a component constrains the behavior of the component and indirectly constrains the behavior of the system. We assume that each component of a system has a behavioral specification, which is a set of complete histories involving the component; the behavioral specification of a component c is denoted by c.behauior. Given the behavioral specifications of a system’s components, the possible behavior of the system is then all complete histories h such that, for all a and x, h 1 a E a.behauior and h 1 x E x.behauior. In other words, any history of a system must be permitted by the specification of each of the system’s components. Notice that the behav- ioral specification of each component describes how the component constrains the occurrence of events in which it participates, and places no constraints on the occurrence of other events.

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 8: Local Atomicity Properties: Modular Concurrency Control

256 - William E. Weihl

As we discuss in Section 2.2.1 below, it is convenient to place more structure on the specifications of objects. Also, our specifications are like languages and can be conveniently described by automatons. In Section 2.2.2 we define state machines, which we will use for describing specifications.

2.2.1 Specifications of Objects. We have found it convenient to specify an object by first describing the object’s sequential, failure-free behavior, and then describing how the object controls concurrency and failures to ensure atomicity. Structuring the specifications of objects in this way makes it easier to reason about many properties of transactions. For example, if all executions of a system are atomic, consistency is preserved if every transaction preserves consistency when executed in isolation with no failures. To check this property, we only need to know how each object and transaction behaves in a sequential, failure-free environment. Since an object’s sequential, failure-free behavior is typically much simpler than its concurrent behavior, it is convenient to describe it separately.

We reflect this structure directly in our model: a specification of an object x consists of two parts, the serial specification (denoted x.serial) and the behavioral specification (denoted x.behavior). The serial specification of an object is intended to model the acceptable behavior of the object in a sequential, failure-free environment, while the behavioral specification describes how the object supports atomicity.

As mentioned above, the behavioral specification of an object x describes the acceptable histories involving x, and consists of a set of complete histories h such that every event in h involves x. We find it convenient when describing specifi- cations, however, for the serial specification of an object to be in a slightly different form from its behavioral specification. Instead of a set of complete histories, we will use a set of operation sequences. An operation is a pair consisting of an invocation and its results. In addition, an operation identifies the object on which it is executed. An operation does not identify a transaction; we have found no need for the serial specification of an object to vary depending on which transaction executes an operation, and indeed we usually find it more convenient to describe the serial specification in a way that is independent of transactions.

We often speak informally of an “operation” on an object, as in “the insert operation on a set object.” An operation in our formal model is intended to represent a single execution of an “operation” as used in the informal sense. For example, the following might be an operation (in the formal sense) on a set object X:

x: [insert(3), ok]

This operation represents an execution of insert on x with argument “3” and result “ok.”

The serial specification of an object describes the acceptable sequences of operation executions in the absence of concurrency and failures. For example, the following operation sequence would be in the serial specification of a set object x that has a member operation that returns true if and only if its argument is in the set:

x: [insert(S), ok] x: [member(3), true]

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 9: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties * 257

The following sequence, however, would not:

x: [insert(3), ok] x: [member(3), false]

In the next section, we define state machines and show how they can be used to give concise descriptions of serial specifications of objects.

2.2.2 State Machines. Informally, a state machine consists of a collection of states and a collection of transitions. The transitions can be used to change the state of the machine. A step of the machine consists of a single transition; the machine executes steps one at a time.

We begin with some notation. We use the notation -+P to denote a partial function. The symbol I denotes “undefined” and will be used to indicate when a partial function is not defined for a given set of arguments. The symbol ., as mentioned earlier, denotes concatenation of sequences.

Formally, a state machine M consists of a state domain S,; an initial state IM E S,; a collection of transitions T M; and a partial transition function NM: S, x Ti\? -+P S,.

The transition function NM can be extended to finite sequences of transitions in the obvious way; that is, if S is a state, T is a transition, and Tseq is a finite sequence of transitions, then

N,(S, A) = S; NM& Tseq) = I;

N,?(S, Tseq . T) = NM(NM(S, Tseq),*T).

If Tseq is a sequence of transitions for machine M, we will sometimes use the notation Tseq(S) for NM (S, Tseq).

If Tseq(S) # I, we say that Tseq is defined in S. We say that a sequence of transitions Tseq is accepted by a machine M if Tseq is defined in I,.

We may easily associate a set of sequences with a machine: given a machine M, define the language of M (denoted L(M)) to be the set of all finite sequences of transitions that are accepted by M.

A state machine is a convenient tool for describing the serial specification of an object. We define the transitions of a machine to be the operations on the object, and choose a state domain and a transition function such that the language of the machine is the desired set of operation sequences. For example, the serial specification of a set object x: could be taken to be the language of the state machine in Figure 1. A set object provides three operations: insert, delete, and member. Insert adds a specified item to the set object. Delete removes a specified item from the set object. Member determines whether a specified item is an element of the set object. The transition function is described by giving, for each transition, a precondition describing the set of states in which it is defined, and the changes to the state caused by the transition. We use “when (expr),” where (expr) is a Boolean expression, to describe preconditions for transitions. If the precondition is omitted from the description, it is assumed to be true. We use “changes (state) to (expr)” to describe the relationship between the state before a transition and the state after the transition. If no change is listed for a transition, the state is assumed to be unchanged.

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 10: Local Atomicity Properties: Modular Concurrency Control

258 * William E. Weihl

States: sets of items initially 0

Transitions: (x:[insert(i),ok], x:[delete(i).ok]. x:[member(i),b]: i is an item and b is a boolean)

N(s,x:[insert(i).ok]): changes s to su (i)

N(s,x:[delete(i),ok]): changes s to s-Ii]

N(s,x:[member(i),true]): when k s

N(s,x:[member(i),false]): when ie s

Fig. 1. Serial specification of a set object X.

The reader may easily verify that the language of the state machine described in Figure 1 contains the operation sequences expected of a set object with insert, delete, and member operations: member returns true if and only if the item has not been deleted since it was last inserted. We use this specification of the serial behavior of a set object in examples throughout the rest of this paper.

3. GLOBAL ATOMICITY

Informally, a history of a system is atomic if the committed transactions in the history can be executed in some serial order and have the same effect. In our model, the permissible serial executions are characterized by the serial specifi- cations of the objects. Thus, whether a history is atomic depends on these serial specifications. In this section we provide a formal definition of atomicity in terms of the serial specifications of the objects in a system.

Since serial specifications are sets of operation sequences, not sets of histories, we need to establish a correspondence between histories and operation sequences. We do this as follows: We say that a history is serial if events for different transactions are not interleaved. If h is a serial history and a,, . . . , a,, are the transactions in h in the order in which they appear, then we can write h as h 1 a1 . . . . . h 1 a,. We say that a history h is failure-free if aborted(h) = 0. Now, if h is a serial failure-free history, we define opseq(h) (the operation sequence corresponding to h) as follows: For a transaction a, opseq(h 1 a) is the operation sequence obtained from h 1 a by pairing each invocation event with its corresponding termination event, and by discarding commit events and pending invocation events. Let al, . . . , a,, be the transactions in h in the order in which they appear; then opseq(h) is defined to be opseq(h I a,) . . . . . opseq(h I a,).

For example, if h is the serial failure-free history

(insert(3), x, b) (ok, x, b:, (delete(2), x, b) (ok x, b) (commit, x, b) (member(3), x, a) (true, x, a) (commit, x, a)

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 11: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties * 259

then opseq(h) is the operation sequence

x: [insert(3), ok] x: [delete(2), ok] x: [member(3), true]

Similarly, if h is the serial failure-free history

(insert(3), x, a) (ok, x, a) (delete(2), x, a)

then opseq(h) is the following operation sequence:

x: [insert(3), ok]

We say that a serial failure-free history h is acceptable at x if opseq(h 1 x) E x.serial; in other words, if the sequence of operations in h involving x is permitted by the serial specification of x. A serial failure-free history is acceptable if it is acceptable at every object x.

For example, suppose that x is an integer set object with a serial specification as given in Figure 1. If h is the serial failure-free history

(insert(3), x, b) (ok x, b) (commit, x, b) (member(3), x, a) (true, x, a) (commit, x, a)

then opseq(h) is the operation sequence

x: [insert(3), ok] x: [member(3), true]

which is in x.serial. Thus, h is acceptable. On the other hand, if h is the history

(insert(3), x, b) (ok, x, b) (commit, x, b) (member(3), x, a) (false, x, a) (commit, x, a)

then h is not acceptable, since opseq(h) is not in xserial. We say that two histories h and k are equivalent if every transaction performs

the same steps in h as in k, that is, if h 1 a = k 1 a for every transaction a. If h is a history and T is a total order on transactions, we define serial(h, T) to be the serial history equivalent to h in which transactions appear in the order T. Thus, if a,, . . . , a,, are the transactions in h in the order T, then serial(h, T) = hia,. . . . . hia,.

The following lemma asserts the independence of the serializing operator and the restriction operator.

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 12: Local Atomicity Properties: Modular Concurrency Control

260 - William E. Weihl

LEMMA 3. If h is a history, X is a set of objects, and T is a total order on transactions, then serial(h 1 X, T) = serial(h, T) 1 X.

PROOF. Let al, . . . . a, be the transactions in h in the order T. The following equalities show the desired result:

serial(h(X, T) = (h(X) (al . . . . . (h(X) 1 a,; = (h) a,) 1 X - . . . . (h 1 a,) IX by Lemma 1; = (h 1 a, . . . . . h ( a,) I X by Lemma 2; = serial(h, T) I X. 0

If T is a total order on transactions, we then say that a failure-free history h is serializable in the order T if serial(h, T) is acceptable. In other words, h is serializable in the order T if, according to the serial specifications of the objects, it is permissible for the transactions in h, when run in the order T, to execute the same steps as in h. We say that a failure-free history h is serializable if there exists a total order T on transactions such that h is serializable in the order T.

For example, if h is the failure-free history

(member(3), x, a) (insert(3), x, b) (ok, x, b) (true, x, a) (commit, x, b) (commit, x, a)

and T is a total order in which b precedes a, then h is serializable in the order T: serial(h, T) is the history

(insert(3), x, b) (ok, x, b) (commit, x, b) (member(3), x, a) (true, x, a) (commit, x, a)

and as illustrated above, this history is acceptable. Lemma 4 describes the relation between serializability of a history and serial-

izability of its subhistories at each object.

LEMMA 4. If h is a history and T is a total order on transactions, then h is serializable in the order T if and only if, for every object x, h ) x is serializable in the order T.

PROOF. Follows easily from the definitions and Lemma 3. 0

Now, define permanent(h) to be h I committed(h). We then say that h is atomic if permanent(h) is serializable. Thus, we formalize recoverability by throwing away events for noncommitted transactions and requiring that the committed transactions be serializable. ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 13: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties l 261

For example, if x is an integer set as above and h is the history

(member(3), x, a) (insert(3), x, b) (ok, x, b) (true, x, a) (commit, x, b) (delete(3), x, c) (ok, x, c) (commit, x, a) (abort, x, c)

then permanent(h) is the failure-free history

(member(3), x, a) (insert(3), x, b) (ok, x, b) (true, x, a) (commit, x, b) (commit, x, a)

which, as illustrated above, is serializable. Thus, h is atomic. On the other hand, the history

(member(2), x, a) (true, x, a) (commit, x, a)

is not atomic, since xserial does not contain the following sequence:

x: [member(2), true]

The final lemma asserts that permanent commutes with restriction to an object for complete histories. (Recall that a complete history is one in which every transaction completes at every object at which it invokes operations.)

LEMMA 5. If h is a complete history and x is an object, permanent(h) 1 x = permanent(h 1 x).

PROOF. We show that permanent(h) ] x is a subsequence of permanent(h 1 x); a similar argument shows that permanent (h ] X) is a subsequence of perma- nent(h) ] x. Since both histories are subsequences of h, it suffices to show that every event appearing in permanent(h) ] x also appears in permanent(h I x). Suppose e is an event in permanent(h) I x. Let a be the transaction that partici- pates in e. By the definition of restriction, x must also participate in e. Thus, e also appears in h ] x. Since e appears in permanent(h) ] X, a must commit in h; since h is complete and h ] a ] x # A, a must commit in h ] x. Thus, e appears in permanent(h I x). q

Our definition of atomicity is similar to the definition of serializability in [33], where it is assumed that some underlying recovery mechanism handles aborts of transactions, and the formal analysis considers only events for committed trans- actions. It is different in that we include events for aborted and active transactions in our formal model; as shown in [19], [44], and [45], this facilitates the precise description and verification of on-line support for recoverability. It also differs

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 14: Local Atomicity Properties: Modular Concurrency Control

262 . William E. Weihl

in that the definition of serializability is based on user-supplied specifications of the acceptable serial behavior of objects, rather than a free interpretation as in [33]. As we show in the next section, this enables us to permit more concurrency.

Our model differs from models commonly used to study concurrency control in another, subtler fashion. A common approach to studying concurrency control is to model the system as composed of transactions, a scheduler, and a storage system. The scheduler takes requests for operations from transactions and, perhaps after delaying some of the requests, forwards the requests to the storage system. The storage system then acts on the requests in the order they are presented to it. The result of this structure is that an interpretation is placed on the order in which operations are scheduled by the scheduler-this is the order in which they are “executed.” One can think of concurrency control as being done in the scheduler, and recovery as being done in the storage system. Recovery is not modeled explicitly, however; instead, the informal assumption that some recovery mechanism ensures that aborted transactions have no effect is formal- ized by studying only executions in which all transactions commit.

The typical model used for the storage system assumes an update-in-place recovery strategy in which an attempt to read a storage location returns the most recent value written to that location. As shown in [45], the assumption of an update-in-place recovery algorithm rules out concurrency control algorithms that work with other recovery methods. In contrast, our model places no interpretation on the order of events in a history. Our definition of atomicity constrains the observable behavior of the system as seen by the transactions, but makes no assumptions about the internal structure of the individual objects. Such assump- tions are useful for studying particular protocols. However, different assumptions (e.g., a different semantics for the “storage system”) are needed to study different protocols (e.g., see [5] and [34]). By avoiding such assumptions altogether, we obtain a more basic definition of atomicity that applies to a wider range of protocols.

4. LOCAL ATOMICITY PROPERTIES

We are interested in ways of ensuring that all possible histories of a system are atomic. As discussed in Section 2, the histories of a system are constrained by the specifications of the components of the system. In this section we investigate several properties of individual objects that ensure atomicity of transactions using the objects. We call such properties local atomicity properties. More precisely, a local atomicity property is a property P of specifications of objects such that the following is true: if the specification of every object in a system satisfies P, then every history in the system’s behavior is atomic.

The problem that must be solved in designing a local atomicity property is to ensure that the objects agree on at least one serialization order for the committed transactions. Solving this problem can be difficult because each object is aware only of the events in which it participates. In other words, each object has purely local information; no object has complete information about the global computa- tion of the system.

There are many different protocols (e.g., two-phase locking [12] and multi- version timestamping [36]) that ensure agreement among objects. As the follow- ing example illustrates, these protocols are not always compatible. Consider two ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 15: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties - 263

objects X and Y, each with read and write operations, and each with initial value 0. Suppose that X is implemented using two-phase locking and Y is implemented using multiversion timestamping. Under read-write locking, a transaction that reads an object gets the most recent value written (subject to the need to acquire appropriate locks first). Under multiversion timestamping, however, a transac- tion that reads an object may get an “old” value, if the timestamp of the reading transaction is less than the timestamp of a transaction that already wrote the object.

Now suppose there are two transactions A and B, with timestamps 1 and 2, respectively. Consider the following execution:

B reads X, receiving 0. B writes 1 into Y. B commits. A reads Y, receiving 0. A writes 1 into X. A commits.

Notice that this execution is not serializable: in a serial execution, the second transaction should see the value written by the first, but both A and B read the initial values of the objects. However, the execution is atomic at each object: at X, B is serializable before A; and at Y, A is serializable before B.

The problem in the example above is that X and Y use incompatible protocols to ensure atomicity. If both objects used two-phase locking or both used multi- version timestamping, the above execution could not occur, and atomicity would be guaranteed. Thus, to ensure that objects agree on a serialization order for committed transactions, a local atomicity property must require more than simply that every history in an object’s behavioral specification is atomic.

One might expect there to be a single “best” local atomicity property. Indeed, this would be the ideal situation. Unfortunately, this is not the case. In the remainder of this section, we present three different local atomicity properties, highlighting the way in which agreement is reached. We also show that each property is optimal, in a sense to be defined below. Our optimality results imply that no local property of objects is both necessary and sufficient for global atomicity.

The three properties presented in this section provide formal characterizations of the behavior of three different classes of protocols, exemplified by two-phase locking, multiversion timestamping, and hybrid protocols (e.g., see [43]). Like our definition of atomicity, each of the properties is based on user-supplied specifications of the acceptable serial behavior of objects, thus permitting imple- mentations that achieve greater concurrency than is possible when operations are simply characterized as reads and writes.

The remainder of this section is divided into three subsections. In each we define a different local atomicity property, prove it correct and optimal, and discuss its relationship to the others presented already.

4.1 Dynamic Atomicity

Two-phase locking protocols [6, 12, 211 determine a serialization order for transactions dynamically, based on the order in which transactions invoke oper- ations and obtain locks on objects. Our first local atomicity property characterizes

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 16: Local Atomicity Properties: Modular Concurrency Control

264 * William E. Weihl

the behavior of protocols, including two-phase locking protocols, that are dynamic in this sense. We call this property dynamic atomicity.

Informally stated, the fundamental property of protocols characterized by dynamic atomicity is the following: if the sequence of operations executed by one committed transaction conflicts with the operations executed by another com- mitted transaction, then some of the operations executed by one of the trans- actions must occur after the other transaction has committed. Locking protocols (and all pessimistic protocols) achieve this property by delaying conflicting operations; optimistic protocols [23] achieve this property by allowing conflicts to occur, but aborting conflicting transactions to prevent conflicts among com- mitted transactions.

The remainder of this section is divided into two subsections. In the first, we present dynamic atomicity and prove that it is a local atomicity property. In the second, we define optimality and show that dynamic atomicity is optimal. We do not discuss implementations in this paper; the interested reader is referred to [42], [44], and [45] for a description and verification of locking-based implemen- tations of dynamic atomicity.

4.1.1 Definition of Dynamic Atomicity. We can describe dynamic atomicity precisely as follows. If h is a history, define precedes(h) to be the following relation on transactions: (a, b ) E precedes(h) if and only if there exists an operation invoked by b that terminates after a commits in h. The events need not occur at the same object. The relation precedes(h) captures formally the intuitive concept described above of an operation of one transaction occurring after another transaction has committed.

For example, if x is a set object as before, and h is the history

(insert(Z), x, a) (ok, x, a> (member(3), x, b) (false, x, b) (commit, x, b) (commit, x, a)

then precedes(h) is the empty relation, while if h is the history

{insert(2), x, a) (ok x, a) (member(3), x, b) (commit, x, a) (false, x, b) (commit, x, b)

thenprecedes contains the pair (a, b). Note that, for any history h,precedes (h) is a partial order.

The following lemma provides the key to our definition of dynamic atomicity.

LEMMA 6. If h is a history and x is an object, then precedes (h 1 x) C precedes (h).

If h is a history of the system, each object has only partial information about precedes(h). However, if each object x ensures local serializability in all orders consistent with precedes(h ) x), we are guaranteed global serializability in all ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 17: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties l 265

orders consistent with precedes(h). To be precise, we have the following definition of dynamic atomicity: We say that a history h is dynamic atomic if permanent(h) is serializable in every total order consistent with precedes(h). In other words, every serial history equivalent t,o permanent (h), with the transactions in an order consistent with precedes(h), must be acceptable.

For example, the following history h is atomic, but not dynamic atomic:

(member(3), x, a) (insert(3), x, b) (ok, x, b) (false, x, a) (member(3), x, c) (commit, x, b) (true, x, c) (commit, x, a) (commit, x, c)

Permanent(h), which is the same as h, is equivalent to the acceptable serial history

(member(3), x, a) (false, x, a) (commit, x, a) (insert(3), x, b) (ok, x, b) (commit, x, b) (member(3), x, c) (true, x, c) (commit, x, c)

and thus is serializable in the order a followed by b followed by c (written a-b-c). However, since precedes(h) contains only the single pair (b, c ), permanent(h) must also be serializable in the orders b-a-c and b-c-a for h to be dynamic atomic. This is not the case; for example, the serial history

(insert(3), x, b) (ok, x, b) (commit, x, b) (member(3), x, a) (false, x, a) (commit, x, a) (member(3), x, c) (true, x, c) (commit, x, c)

is not acceptable. As another example, the history

(member(2), x, a) (insert(3), x, b) (ok, x, b) (false, x, a) (member(3), x, c) (commit, x, b) (true, x, c) (commit, x, a) (commit, x, c)

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 18: Local Atomicity Properties: Modular Concurrency Control

266 - William E. Weihl

is dynamic atomic. Precedes (h ) contains the single pair (b, c ) , and permanent (h ) is serializable in the orders a-b-c, b-u-c, and b-c-a.’

We say that an object x is dynamic atomic if every history in xbehavior is dynamic atomic. The following theorem justifies our claim that dynamic atom- icity is a local atomicity property:

THEOREM 7. If every object in a system is dynamic atomic, then every history in the system’s behavior is atomic.

PROOF. Suppose every object in a system is dynamic atomic, and let h be a history of the system. Precedes(h) is a partial order, so let T be a total order on transactions that is consistent with precedes(h). By Lemma 6, precedes(h 1 x) G precedes(h), so T is also consistent with precedes(h 1 x) for every x. Since each object is dynamic atomic, permanent(h 1 X) is serializable in every total order consistent with precedes(h 1 x); in particular, it is serializable in the order T. By Lemmas 4 and 5, permanent(h) is serializable in the order T. Thus, h is atomic. 0

4.1.2 Optimality. Dynamic atomicity is optimal: there is no other local atom- icity property that is strictly more permissive. The paragraphs below state this result precisely and provide a proof.

Recall that a local atomicity property P is any property P of specifications of objects such that the following is true: if the specification of every object in a system satisfies P, then every history in the system’s behavior is atomic. We say that a property P is weaker (or more permissive) than a property Q if every specification that satisfies Q also satisfies P, in other words, if Q implies P. A property P is strictly weaker than a property Q if P is weaker than Q and if Q is not weaker than P. Note that, if P is strictly weaker than Q, then there exists some specification that satisfies P and does not satisfy Q. If we equate the level of concurrency permitted by a property with the set of behaviors permitted by the property for a given serial specification, then, if P is strictly weaker than Q, P permits more concurrency than Q.

We say that a local atomicity property P is optimal if no local atomicity property is strictly weaker than P. The following theorem shows that dynamic atomicity is optimal:

THEOREM 8. For systems using the euents described in this section, dynamic atomicity is optimal.

The proof of this theorem relies on a technical lemma (Lemma lo), which shows that under certain conditions two histories at separate objects can be combined into a single history involving both objects. We present the lemma first and then the proof of the theorem.

First, we need some definitions. If h is a history, define the relation commit- order(h) on transactions to contain all pairs (a, b) such that a, b E committed(h)

’ We note in passing that most of our examples of histories include only one operation per transaction. All our definitions permit a transaction to execute a sequence of operations on one or several objects. Examples containing more than one operation per transaction would be longer, and in most cases little additional insight would be provided.

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 19: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties l 267

and the first commit event for a in h occurs before the first commit event for b in h. Note that commit-order(h) is a partial order on transactions and that it totally orders committed(h).

It is convenient to introduce additional events into the histories to capture the constraints needed for the proof of Lemma 10. The completion events (commit, x, a) and (abort, x, a) discussed so far correspond to the object x: learning of the completion (commit or abort) of the transaction a. We introduce the additional decision event (decide, a) corresponding to the decision by trans- action a to commit. (We do not need decision events for aborted transactions in the proof, so we do not introduce them.) If h is a history and H is a sequence of invocation, termination, commit, abort, and decision events, we say that H is a decision-extension of h if

-the subsequence of H consisting of nondecision events is just h; -only committed transactions decide in H; and -for each a E committed(h), H 1 a consists of op-euents(h 1 a), followed by exactly

one decision event for a, followed by one or more commit events for a.

In other words, H is simply h with events inserted to indicate the point at which each committed transaction decided to commit; the decision to commit must come after the last operation invoked by the transaction returns and before any object is told of the commit.

Given an extended history H, let decision-order(H) be the total order on transactions that decide in H that orders a before b exactly when the decision event for a occurs before the decision event for b in H.

The following lemma is the key to the proof of Lemma 10. From it we can conclude that precedes(h ( 3~) captures precisely the local information that x has about the actual order of the commit decisions made by transactions: the commit decisions could have been made in any order consistent with precedes(h ) x).

LEMMA 9. If h is a history and T is a total order on transactions consistent with precedes(h), then there exists a decision-extension H of h such that decision- order(H) C T.

PROOF. By induction on the size of committed(h). If the size is 0, simply let H = h. Otherwise, suppose the size is n > 0, let ai, . . . , a, be the transactions in committed(h) in the order given by T, and assume the lemma holds for all histories with fewer than n committed transactions. Let k = h 1 ACT - (a,), where ACT is the set of all transactions. Then k has only n - 1 committed transactions, so by induction the lemma holds for k. Since precedes(k) C_ precedes(h), T is consistent with precedes(k). Therefore, there is a decision- extension K of k such that decision-order(K) C T.

We can write k as k, . . . . . k,, where no hi is empty, h = fO . k, ’ fi. . . . . fmvl . k,, . f,,,, and h 1 a, = f. . . . . . f,,,. Similarly, we can write K as go * g1 * * . . * g,, where, for 1 5 i 5 m, ki is a subsequence of gi, and gi starts with an event from ki. We obtain N as follows. First, insert the events in h that are not in k into K immediately before the events that follow them in h, adding a decision event for a, immediately before its first commit event. More precisely, let j be such that the first commit event for a, occurs in fj, and define f t! to be fi

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 20: Local Atomicity Properties: Modular Concurrency Control

268 - William E. Weihl

if i # j, and to be fi with (decide, a,) inserted before the first commit event if i=j.Now,letH=go. f6. . . . -g,. fk.

.We are not quite done, since it need not be the case that decision-order(H) C T. To ensure this, modify H as follows. Let d be the subsequence of H consisting of decision events that occur after (decide, a,, ). Modify H by deleting the events in d and then by inserting d immediately before (decide, a,, ). We claim that the resulting sequence has the desired properties. It is immediate that the resulting sequence satisfies the constraint on decision-order; the only question is whether it is a decision-extension of h. We show that it is by contradiction. Suppose it is not; then some decision event in d for a transaction oi must occur before a termination event e for ai. For this to be true, the termination event e must follow the first commit event for a,, implying that (a,, ai > E precedes(h). Since T is consistent with precedes(h), and T orders a,, after a;, this is a contradiction. 0

The next lemma is the key to the optimality results in this and later sections:

LEMMA 10. Let h, and h, be complete histories such that h, = h, ) x, h, = h, 1 y, aborted = 0, committed = committed( h, is serial, and commit- order(h,) is consistent with precedes(h,). Then there exists a complete history h such that h ( x = h,, h 1 y = h,, and for all objects z other than x and y, h 1 z = A.

PROOF. Let T be a total order on transactions consistent with commit- order(h,) and with precedes(h,). It follows from Lemma 9 that there exists a decision-extension H, of h, such that decision-order(H,) is a subset of T. In other words, decision-order(H,) = commit-order(h,). Obtain H from H, by inserting op-euents(h, 1 a,) before (decide, ai) for each ai that is committed in h,, and then by inserting the commit events for ei from h, immediately after (decide, ai). Finally, obtain h by deleting decision events from H. It is easy to check that the sequence h thus obtained has the desired properties. Cl

We now present the proof of Theorem 8:

PROOF (Theorem 8). The proof proceeds by contradiction. Suppose dynamic atomicity is not optimal. Then there exists a local atomicity property P that is strictly weaker than dynamic atomicity. We will exhibit a system composed of objects satisfying P and show that there is a nonatomic history of that system, thus contradicting the claim that P is a local atomicity property.

Since P is more permissive than dynamic atomicity, there must be a specifi- cation S, of an object x such that S, satisfies P but x is not dynamic atomic. In particular, there must be at least one complete history h, in xbehauior that is not dynamic atomic, that is, such that permanent(h,) is not serializable in at least one total order T consistent with precedes(h,). (Note that the definitions imply that it is also not serializable in any order that agrees with T on commit- ted(h,).) We will construct an object y whose specification S, satisfies P and contains a complete history hY involving the committed transactions in h,. Now, consider a system containing x, y, and all the transactions in h,. We will choose h, so that h, is serializable only in orders that agree with T on committed( and there is a history h of this system such that h 1 x = h, and h ( y = h,. Since ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 21: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties - 269

States: integers initially 0

Transitions: (y:[increment,i]: i is an integer) N(s,y:[incremenfj]):

when i=s+l changes s to s+l

Fig. 2. Serial specification of a counter ob- ject y.

permanent(h,V) is serializable only in orders that agree with Ton committed( and permanent (h,) is not serializable in those orders, it follows from Lemma 4 that permanent(h) is not serializable. Thus, h is not atomic.

Construction of y. The construction of y is as follows. Let y have a single operation called increment. Y is intended to behave as a counter: its state is initially zero, and each invocation of the increment operation increments the state of y and returns the resulting value. A state machine describing the serial specification of y appears in Figure 2.

The operation sequences in y.serial have the following form:

y: [increment, 11 y: [increment, 21

y: [increment, n]

Let y.behauior be the largest set of complete histories such that y is dynamic atomic; that is, let y.behavior contain all dynamic atomic complete histories h such that h = h 1 y. Since P is weaker than dynamic atomicity, S, satisfies P.

Choice of h,. Now, let a,, a2, . . . , a,, be the committed transactions in h, in the order T, and let h, be the following serial history in y.behavior.

(increment, y, a, ) (1, Y, a,) (commit, y, a, ) (increment, y, a,) (2, Y, a2) (commit, y, a,)

(increment, y, a,) (n, Y, an) (commit, y, a,)

Note that h, is serializable only in orders that agree with Ton committed( Existence of h. Notice that commit-order(h,) is consistent with precedes(h,).

It is easy to check that the other hypotheses of Lemma 10 are satisfied, and the existence of h follows directly from that lemma. 0

It is important to realize that dynamic atomicity is not a protocol for synchro- nizing transactions. Rather, it is a semantic constraint on the amount of concur- rency that can be permitted by an object. The optimality result shown above

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 22: Local Atomicity Properties: Modular Concurrency Control

270 l William E. Weihl

implies that dynamic atomicity defines an upper bound on the concurrency that can be permitted by an object. For example, the locking protocoIs of [6] and [al] satisfy the constraints imposed by dynamic atomicity, but are suboptimal: while sufficient to ensure dynamic atomicity (and thus atomicity when all objects are dynamic atomic), they achieve strictly less concurrency than permitted by dynamic atomicity.

There are two reasons why locking protocols do not achieve all the concurrency permitted by dynamic atomicity. First, no information about the state of an object is used to synchronize transactions. The effect of this is that operations that conflict in a few states are treated as conflicting regardless of the actual state of the object. Second, synchronization is based on conflicts between oper- ations; no information is used about the sequence of operations executed by each transaction. Detailed examples illustrating the limitations of locking can be found in [42], along with nonlocking protocols that avoid these limitations.

4.2 Static Atomicity

Protocols characterized by dynamic atomicity determine a serialization order for transactions based on the dynamics of the execution of transactions. In contrast, some timestamp protocols (e.g., see [36]) determine a serialization order for transactions statically, based on timestamps chosen when transactions start. Our second local atomicity property characterizes the behavior of protocols that are static in this sense. We call this property static atomicity.

The remainder of this section is divided into two subsections. In the first, we define static atomicity and prove that it is a local atomicity property. In the second, we show that static atomicity is optimal.

4.2.1 Definition of Static Atomicity. Static atomic objects ensure that trans- actions are serializable in a predetermined order. We model this behavior as follows. Suppose TS (for “timestamp”) is a total order on transactions. We say that a history h is static atomic with respect to TS if permanent(h) is serializable in the order TS. For ease of exposition, in the remainder of this paper we will assume that TS is an arbitrary but fixed total order on transactions, and will omit the phrase “with respect to TS.” In other words, wherever we write “static atomic” the reader should read “static atomic with respect to TS.”

For example, suppose x is a set object as before. Suppose that a and b are transactions, and that TS orders b before a. Then the following history h is atomic (and even dynamic atomic), but not static atomic:

(member(3), x, a) (false, x, a) (commit, x, a) (insert(3), x, b) (ok, x, b) (commit, x, b)

Permanent(h) is a serial history and is serializable in the order a-b. However, permanent(h) is not serializable in the order b-a, which is the order specified by TS. ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 23: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties * 271

As another example, the history

(insert(3), x, a) (ok, x, a) (commit, x, a) (member(3), x, b) (false, x, b) (commit, x, b)

is static atomic: permanent(h) is serializable in the order TS. We say that an object is static atomic if every history permitted by the object’s

behavioral specification is static atomic. The following theorem verifies that static atomicity is a local atomicity property:

THEOREM 11. If every object in a system is static atomic, then every history in the system’s behavior is atomic.

PROOF. Suppose that every object in a system is static atomic, and let h be a history of the system. By the definition of static atomicity, permanent(h ) x) is serializable in the order TS. By Lemmas 4 and &permanent(h) is also serializable in the order TS, so h is atomic. 0

4.2.2 Optimality. Static atomicity, like dynamic atomicity, is optimal.

THEOREM 12. For systems using the events described in this section, static atomicity is optimal.

PROOF. The proof proceeds by contradiction, along the lines of the proof of Theorem 8. Suppose P is a local atomicity property that is strictly weaker than static atomicity. We will exhibit a system composed of objects satisfying P and show that there is a nonatomic history of that system, thus contradicting the claim that P is a local atomicity property.

Since P is more permissive than static atomicity, there must be a specification S, of an object x such that S, satisfies P but x is not static atomic. In particular, there must be at least one complete history h, in xbehavior that is not static atomic; that is, such that permanent(h,) is not serializable in the order TS (or any order that agrees with TS on committed(h We will construct an object y whose specification satisfies P and contains a complete history h, involving the committed transactions in h,. Now, consider a system containing x, y, and all the transactions in h,. As in the proof of Theorem 8, h, will be chosen so that it is serializable only in orders that agree with TS on committed( and there is a history h of this system such that h 1 x = h, and h 1 y = h,. As in the proof of Theorem 8, it then follows that h is not atomic.

Construction of y. The serial specification of y is the same as in the proof of Theorem 8 and is described by the machine in Figure 2. Let y.behavior be the largest set such that y is static atomic. Notice that, while the serial specification of y is the same as in the proof of Theorem 8, the behavioral specification is different. Since P is weaker than static atomicity, S, satisfies P.

Choice of h,. Now, let al, a2, . . . , a,, be the transactions in committed in the order commit-order(h,). Let order: (al, . . . , a,) -+ (1, 2, . . . , n] map the a;

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 24: Local Atomicity Properties: Modular Concurrency Control

272 * William E. Weihl

to the integers between 1 and n such that order(ui) < order(uj) if and only if TS orders ai before oj. Let h, be the following serial history in y.behavior:

(increment, y, a, ) (orderh), Y, aI ) (commit, y, a, ) (increment, y, a2 ) (ordedad, Y, a2) (commit, y, a,)

(increment, y, a,) (order&), Y, a,) (commit, y, a, )

Note that h, is serializable only in orders that agree with TS on committed (h,). Existence of h. The existence of h follows directly from Lemma 10. Cl.

Dynamic atomicity and static atomicity are different: each permits histories that the other does not (e.g., see the examples at the start of Section 4.2.1). Notice also that the proof that dynamic atomicity is optimal still works even if one assumes there is a predefined total order on transactions, as we assume in defining static atomicity. This implies that optimal does not mean “best,” but rather that nothing else is strictly better. Also, whether a local atomicity property is optimal depends on the information available to objects about the history of the entire system. The optimality results shown above for dynamic and static atomicity are based on the assumption that the only information available to an object about the history of the system is the events that involve the object. More events, or more information about the behavior of the transactions and the other objects, can provide more information and permit more concurrency. Examples of this phenomenon are given in Section 4.3.

The existence of multiple optimal local atomicity properties also implies that a system designer must choose one of these properties for the entire system; this choice must be made fairly early during the design of a system and can be difficult to change. We return to this issue in Section 5.

4.3 Hybrid Atomicity

Our final local atomicity property, which we call hybrid utomicity, characterizes the behavior of protocols that exhibit some of the characteristics of dynamic atomic protocols and some of the characteristics of static atomic protocols. Examples of such protocols include the mixed methods of [4] and multiversion schemes such as those in [5], [8], [ll], and [43]. Static atomic protocols work well in situations in which read-only transactions predominate, whereas dynamic atomic protocols appear to work better when updates predominate. Hybrid protocols combine these techniques to provide good performance regardless of the mix of update and read-only transactions.

Hybrid atomicity is based on two ideas. First, we partition transactions into two classes: read-only transactions and update transactions. Intuitively, a read- only transaction is one that does not invoke any operations that change the state of an object. A precise definition of read-only transactions is given below. ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989

Page 25: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties - 273

As in Reed’s implementation of static atomicity, timestamps for read-only transactions are chosen when they begin execution. Timestamps for update transactions, however, are chosen dynamically as they commit. The system ensures that the timestamp order on updates is consistent with the precedes order at each object; objects can use this property to ensure that updates are serializable in timestamp order.

When a read-only transaction with timestamp t invokes an operation on an object, the object computes the result of the operation by including the effects of all operations executed by committed update transactions with timestamps less than t. The system also ensures that update transactions that commit later choose a timestamp greater than t, thus preventing the results returned to the read-only transaction from being invalidated by an update that commits later.

The remainder of this section is divided into four subsections. In the first, we define what it means for a transaction to be read-only. In the second, we describe some additional events needed to define hybrid atomicity. In the third, we define hybrid atomicity and prove that it is an optimal local atomicity property. Finally, in the fourth, we compare hybrid atomicity to static atomicity and dynamic atomicity.

4.3.1 Read-Only Transactions. A transaction is read-only if every operation executed by the transaction is read-only. All other transactions are considered to be update transactions.

Whether an operation on an object is read-only depends on the serial specifi- cation of the object. Formally, we define a read-only operation as follows. Given a set OseqSet of operation sequences and an operation sequence Oseql, we define the future of Oseql in OseqSet, future(Oseq1, OseqSet), to be the set of all finite operation sequences Oseq2 such that Oseql . Oseq2 E OseqSet. We define an operation 0 on an object x to be read-only if, whenever Oseq E xserial and Oseq . 0 E xserial, future(Oseq, xserial) = future(Oseq . 0, xserial). In other words, executing 0 does not change what can be executed in the future.

If the serial specification of an object happens to be described by a state machine M, then we can define an operation 0 to be read-only if NM(S, 0) = S for all states S in which 0 is defined. This definition differs from the first definition only if the same set of sequences is accepted from two states of M (i.e., the possible future sequences are the same regardless of which of the two states we start in). In this case an operation might be considered read-only according to the first definition but not according to the second, if executing the operation changes the state of M but not the future sequences from that point.

4.3.2 Additional Events. To define hybrid atomicity precisely, we need to introduce some new events that describe the timestamps chosen by transactions. In addition, we must partition the set of transactions into two subsets: the updates (written a, b, and c) and the read-only transactions (written r and s). Timestamps for updates are chosen when they commit, and an object learns of an update’s timestamp when the update commits at the object. We write the event corresponding to the commitment of an update a at object x with timestamp

’ t as (commit(t), x, a). Timestamps for read-only transactions are cho,;en when they start, and an object learns of a read-only transaction’s timestamp when the

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 26: Local Atomicity Properties: Modular Concurrency Control

274 * William E. Weihl

transaction invokes an operation on the object. We model this by introducing initiation events: before invoking an operation on an object, a read-only trans- action must initiate at the object to let the object know its timestamp. We write the event corresponding to the initiation of transaction r at object x with timestamp t as (initiate(t), x, r). We use the term timestamp events to denote the set of all commit events for updates and all initiation events for read-only transactions.

We assume that timestamps are taken from some countable, totally ordered set; in our examples we use natural numbers.

In addition to the well-formedness constraints on event sequences stated in Section 2, we have the following constraints:

-A read-only transaction must initiate at an object before invoking any opera- tions at the object; that is, for every read-only transaction r and every object x, h ] r ] x is empty or begins with an initiation event. In addition, h ] r with the initiation events removed satisfies the well-formedness constraints stated earlier.

-Any two timestamp events for distinct transactions have distinct timestamps. -Any two timestamp events for the same transaction have the same timestamp. -The timestamp order on committed update transactions must be consistent

with the precedes order at each object; that is, if a and b are update transactions that commit in h, and (a, b) E precedes (h ] X) for some object x, then a’s timestamp is less than b’s timestamp.

--If an operation invoked by a read-only transaction r terminates before a commit event occurs for an update transaction a at the same object, then r’s timestamp is less than a’s timestamp.

The first three constraints are obvious. As discussed at the beginning of Section 4.3, the last two constraints are necessary for objects to be able to generate the results of operations on-line. They can be satisfied by using logical clocks [24] to choose timestamps for update transactions (see [43] for details).

For example, the following sequence is well formed:

(insert(3), x, a) (ok, x, a) (commit(2), x, a) (initiate(l), x, r) (member(3), x, r) (false, x, r) (commit, x, r)

The following sequence h, however, is not:

(insert(3), x, a) (ok, x, a) (commit(2), x, a) (member(3), x, b) (true, x, b) (commit(l), x, b) (initiate(2), x, r)

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 27: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties 275

There are two reasons why this sequence is not well formed. First, r and a use the same timestamp, violating the uniqueness property of timestamps. Second, (a, b) E precedes(h 1 x), yet b’s timestamp is less than a’s.

We extend the definition of opseq to histories including timestamp events by having opseq throw away timestamp events in addition to completion events. Acceptability, serializability, and atomicity for histories are then defined as before in terms of opseq.

4.3.3 Definition of Hybrid Atomicity. Informally, a history is hybrid atomic if its committed transactions are serializable in timestamp order. More precisely, let h be a history, and define TS(h) to be the partial order on transactions such that (a, b ) E TS (h) if both a and b commit in h and if u’s timestamp is less than b’s timestamp. We say that h is hybrid atomic if permanent(h) is serializable in all total orders consistent with TS(h).

Notice that TS(h) defines a total order on committed(h). Thus, if perma- nent(h) is serializable in one total order consistent with TS(h), it is serializable in all such orders.

For example, let x be a set object as before; then the following history h is atomic:

(insert(3), x, a) (ok, x, a) (insert(4), x, b) (ok, x, b) (commit(l), x, a) (commit(3), x, b) (initiate(2), x, r) (member(3), x, r) (true, x, r) (member(4), x, r) (true, x, r) (commit, x, r)

since it is serializable in the order u-b-r. However, it is not hybrid atomic, for the following reason: Permanent(h) in timestamp order is the history

(insert(3), x, a) (ok, x, a) (commit(l), x, a) (initiate(2), x, r) (member(3), x, r) (true, x, r) (member(4), x, r) (true, x, r) (commit, x, r) (insert(4), x, b) (ok, x, b) (commit(3), x, b)

which is not an acceptable serial history. ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 28: Local Atomicity Properties: Modular Concurrency Control

276 - William E. Weihl

As another example, the history

(insert(3), x, a) (ok, x, a) (insert(4), x, b) (ok, x, b) (commit(l), x, a) (commit(3), x, b) (initiate(2), x, r) (member(3), x, r) (true, x, r) (member(4), x, r) (false, x, r) (commit, x, r)

is hybrid atomic. We say that an object is hybrid atomic if every history permitted by the object’s

behavioral specification is hybrid atomic. The following theorem verifies that hybrid atomicity is a local atomicity property:

THEOREM 13. If every object in a system is hybrid atomic, then every history of the system is atomic.

PROOF. Suppose that every object in a system is hybrid atomic, and let h be a history of the system. Let T be a total order on transactions consistent with TS(h). By the definition of hybrid atomicity, permanent(h 1 x) is seri- alizable in the order T for every x. By Lemmas 4 and 5, permanent(h) is also serializable in the order T, so h is atomic. 0

Hybrid atomicity is optimal. The proof is similar to those for dynamic and static atomicity; we sketch the main differences here:

THEOREM 14. For systems using the events described in this section, hybrid atomicity is optimal.

PROOF. (Sketch). The proof, like that for dynamic atomicity, proceeds by contradiction. If hybrid atomicity is not optimal, let P be a local atomicity property that is strictly weaker than hybrid atomicity, and let x be an object whose specification satisfies P but is not hybrid atomic. In particular, let h, be a history in xbehavior that is not hybrid atomic, that is, such that permanent(h,) is not serializable in timestamp order. We construct a hybrid atomic object y whose specification contains a history h, involving the committed transactions in h,. We choose h, so that it is serializable only in timestamp order and so that there is a history h of a system containing x and y such that h 1 x = h, and h 1 y = h,. It follows from the construction that h is not atomic and hence that P is not a local atomicity property.

The main differences from the earlier proofs for dynamic and static atomicity lie in the construction of y and h,. To handle read-only transactions, we need to make two changes.

First, since the only operation in the serial specification of the counter object used for y is an “increment” operation, we need to add a read-only operation to ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 29: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties 277

be invoked by the read-only transactions. It suffices to add a simple “get-value” operation that returns the current value of the counter.

Second, to ensure that the transactions in h, are serializable only in timestamp order, we need to be careful about the situation when no update transaction in permanent(h,) appears between a pair of read-only transactions in the timestamp order. We can handle this situation in one of two ways. One approach is to introduce additional update transactions and choose h, so that for every pair of read-only transactions there is at least one update transaction whose timestamp falls between them. To assign timestamps to these additional update transactions, we need another assumption, namely, that timestamps are chosen from a dense set. The other approach is to observe that if permanent(h,) is serializable in an order T that obeys the timestamp ordering between each pair of updates and between each update and read-only transaction, but that may reorder read-only transactions when no update transaction has a timestamp that falls between them, then permanent(h,) must be serializable in timestamp order as well. Thus, it is not necessary to choose h, so that it is serializable only in timestamp order; it can also be serializable in other orders that reflect the timestamp order in all cases except for some pairs of read-only transactions. With either alternative, we obtain a situation in which there is no single total order T such that both permanent(h,) and permanent(h,) are serializable in the order T; this gives the desired contradiction. 0

4.3.4 Discussion. At first glance, hybrid atomicity might not seem very differ- ent from static atomicity: both work by establishing a single global ordering on transactions and by ensuring that transactions are serializable in that order. Static atomicity uses a predetermined order, chosen before transactions begin executing. Hybrid atomicity, in contrast, uses an order determined in part by the order in which updates commit. This difference has a substantial impact on how one builds an on-line implementation of an object. For example, with static atomicity the timestamp order is known for all transactions, both committed and active, when an operation is executed, whereas with hybrid atomicity the time- stamp order is known only for transactions that have already committed.

One simple way to implement hybrid atomicity is to use dynamic atomicity for update transactions, generating timestamps for them so that the timestamp order on updates is consistent with the precedes order at each object, and to compute the results of an operation invoked by a read-only transaction with timestamp t by including the effects of all committed updates with timestamps less than t (see, e.g., [5], [ll], and [43] for more details of this and other ways of imple- menting hybrid atomicity). This simple implementation, like implementations of static atomicity, permits read-only transactions to run without interfering with update transactions; by using dynamic atomicity for updates, however, the problems of static atomicity are avoided.

More complex implementations of hybrid atomicity can allow more concur- rency among update transactions than is permitted by dynamic atomicity. Con- sider, for example, a first-in-first-out queue object z with a serial specification as described by the machine in Figure 3. A FIFO queue object provides two operations: enq and deq. Enq appends a specified item to the back of the queue,

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 30: Local Atomicity Properties: Modular Concurrency Control

278 - William E. Weihl

States: sequences of items initially A

Transitions: (z:[enq(i),ok], z:[deq,i], z:[deq,empty]: i is an item) N(s,z:[enq(i),okl):

changes s to s.i

N(s,z:[deq,i]): when s=i.s’ changes s to s’

N(sr:[deq,emptyl): when s=A

Fig. 3. Serial specification of a FIFO queue object Z.

Deq removes and returns the item at the front of the queue; if the queue is empty, deq signals empty. Hybrid atomicity allows transactions to enqueue items on a FIFO queue in parallel, as is illustrated by the following hybrid atomic history h:

(enq(l), z, a) (ew@L z, b) (ok, z, a) (ok, z, b) (commit(3), z, b) (commit(5), z, a) (deq, z, c) (2, z, c) (deq, z, c) (1, z, c) (commit( 17), z, c)

Notice, however, that this history is not dynamic atomic: precedes(h) = {(a, c ), (b, c) ), but permanent(h) is not serializable in the order a-b-c. Implementations of hybrid atomicity that permit concurrent enqueuing transactions can be found in [19].

Hybrid atomicity can allow more concurrency for updates than dynamic atomicity because the objects have more information, namely, the timestamps assigned to update transactions as they commit. This does not contradict our optimality results, but rather serves to emphasize their dependence on the information available to objects (cf. the work in [22] on the “optimality” of concurrency control protocols, and the dependence of “optimality” on the amount of information available to the protocols). As discussed above, the distinction between read-only and update transactions also provides information that is useful for increasing concurrency.

5. DISCUSSION

One of the most important characteristics of the definitions given in this paper is that they permit information about the specifications of objects to be used to enhance concurrency. This can be seen in the definition of serializability: whether a history is serializable depends on the serial specifications of the objects. If ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 31: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties 279

operations are viewed simply as reads and writes, or as update operations, much less concurrency can be permitted. For example, suppose x is a set object with a serial specification as in Figure 1, and consider the following history:

(member(4), x, a) (false, x, a) (member(l), x, b) (false, x, b) (insert(3), x, a) (ok, x, a) (insert(2), x, b) (ok, x, b) (commit, x, a) (commit, x, b)

This history is dynamic atomic, yet would not be considered serializable if operations were known only to be reads or writes, since both transactions read and then modify the state of the set object.

Another example, a FIFO queue, was shown earlier. We showed that hybrid atomicity permits concurrent transactions to enqueue items on a FIFO queue. Again, if operations were known only to be reads or writes, this level of concur- rency could not be permitted. Other examples, such as bank accounts in which deposits and withdrawals can be executed by concurrent transactions, are dis- cussed in [42], [44], and [45]. Highly concurrent implementations of these and other examples can be found in [19], [42], and [44-461.

Protocols based on a free interpretation of the operations (as used in [33]) cannot achieve this kind of concurrency: each operation is assumed to update the object’s state, implying that transactions cannot access an object concur- rently. For example, two-phase locking using exclusive locks is shown in [22] to be optimal, given that no information is available about the semantics of opera- tions. Similar limitations apply to characterizing operations as reads and writes. The examples above illustrate how a specification of the acceptable serial behav- ior of objects can be used to achieve greater concurrency.

Given that information about the specifications of objects can be used to enhance concurrency, an important question is how much concurrency can be permitted given the serial specification of an object. Our analysis shows that the answer to this question depends on the amount of information available to objects, for example, whether transactions have timestamps and whether certain transactions are read-only. Given a particular level of information, our analysis shows that there may still be more than one possible answer to this question. For example, dynamic atomicity and static atomicity permit different levels of concurrency, yet they use the same information.

The existence of multiple local atomicity properties, all of which are optimal, indicates that a system designer must choose one local property to be used for all objects in the system. This choice can be hard to make and is also difficult to change. This indicates several areas for further research. One area involves developing a basis for making an intelligent choice among local atomicity prop- erties. For example, there is some performance analysis (e.g., [7]) indicating that hybrid protocols have advantages over static and dynamic protocols, but this

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989

Page 32: Local Atomicity Properties: Modular Concurrency Control

280 . William E. Weihl

analysis is far from conclusive. There are also differences in how different local atomicity properties interact with replication methods [16]. Further data com- paring local properties would clearly be useful.

Another useful direction for further work would be to explore other local properties. We have discussed three properties, which together characterize the behavior of many protocols. Not all protocols are characterized by our local properties, however. Examples include non-two-phase locking protocols, such as those in [38] and [39].

The need to choose a local atomicity property heralds future problems. If two applications have been built using different local atomicity properties (e.g., an airline reservation system and a car rental system), it may be difficult to combine them (e.g., by writing transactions that access objects in both systems). This will be a problem as long as there are incompatible protocols and no consensus about which kind of protocol is best. Some recent work has explored ways of connecting systems that use incompatible protocols (e.g., [35]), but the techniques seem to restrict concurrency substantially. Further work is needed to evaluate existing techniques and to develop new ones.

The idea of using the specifications of data to enhance concurrency has become increasingly popular in recent years (e.g., see [l], [3], [6], [21], [37], [41], [42], and [46]). Our approach has several important characteristics that distinguish it from other work.

First, we consider both synchronization and recovery in our model. Although this has little impact on the results presented in this paper, our experience has shown concurrency control and recovery to be tightly coupled, especially in implementations that attempt to provide high levels of concurrency. It is impor- tant to state the basic definitions of correctness abstractly enough that they apply to a wide variety of synchronization and recovery mechanisms; we believe we have achieved this in our definition of atomicity. Support for this claim can be found in the analysis of locking implementations of dynamic atomicity, including recovery, in [42], [44], and [45], and a similar analysis of pessimistic hybrid atomic algorithms in [19] and of optimistic hybrid atomic algorithms in [17].

Second, our model places no interpretation on the order in which operations are scheduled to run. This allows us to use the same basic model and the same definition of correctness (i.e., atomicity) for a wide variety of protocols. Of course, additional structure is important for verifying implementations of protocols, but as discussed earlier, different structures are appropriate for different kinds of protocols.

Third, our specification framework is more general than that used in other work (with the possible exception of [3]): we permit operations to be both partial and nondeterministic. Numerous examples illustrating the practical importance of such specifications can be found in [42] and 1461.

Finally, we have analyzed a system structure in which the state of the system is partitioned among a number of independent objects. Such a structure has a number of useful properties, especially for distributed systems. For example, it is relatively easy to add new kinds of objects, since existing objects are not affected. In general, a local atomicity property captures all the interactions among objects ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 33: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties * 281

that are relevant to the atomicity of transactions. Thus, once a local atomicity property has been chosen, the implementation of each object can be verified purely locally, independently of other objects and of transactions. This locality provides useful modularity. For example, the choices of how much concurrency to provide, whether to use a locking or nonlocking implementation, or whether to use a pessimistic or optimistic approach can all be made locally as part of implementing a single object. (Nonlocking implementations of dynamic atomicity are discussed in [42]; optimistic implementations of hybrid atomicity are dis- cussed in [17].) As a result, these decisions can be changed fairly easily, since only a single object is affected.

The structure we have proposed for specifications of objects, namely, the separation of the serial and behavioral specifications, greatly simplifies the tasks of specifying objects and of reasoning about transactions that share objects. To specify an object, it often suffices to design its serial specification; its behavioral specification can then be taken to be all histories satisfying the local atomicity property chosen for the system. (To reason about the existence or absence of deadlocks or about liveness properties, it may be necessary to constrain the behavioral specifications of objects further.) Similarly, to reason about many properties of transactions, one needs only the serial specifications of the objects shared by the transactions, and the assurance that transactions are atomic. In both cases we have reduced the difficult problem of designing or reasoning about a concurrent, fault-tolerant system to the simpler problem of designing or reasoning about a sequential, failure-free system. Of course, concurrency and failures must be dealt with in the implementation of an atomic type. By using a local atomicity property, however, it is possible to reason about an implementa- tion of an atomic type independently of the transactions in the system and of the other types shared by those transactions.

ACKNOWLEDGMENTS

Numerous people, including all the members of the Programming Methodology Group at MIT, have contributed to the results presented in this paper through their comments and suggestions. John Guttag, Maurice Herlihy, Barbara Liskov, Nancy Lynch, and Gene Stark deserve special thanks for their contributions. In addition, Mark Day and Sharon Per1 contributed comments that greatly improved the presentation of these results.

REFERENCES

1. ALLCHIN, J. E., AND MCKENDRY, M. S. Synchronization and recovery of actions. In Proceedings of the 2nd Annual ACM Symposium on Principles of Distributed Computing (Montreal, Aug. 17- 19, 1983). ACM, New York, 1983, pp. 31-44.

2. ASPNES, J., FEKETE, A., LYNCH, N., MERRITT, M., AND WEIHL, W. A theory of timestamp- based concurrency control for nested transactions. In Proceedings of the Symposium on Very Large Databases (Los Angeles, Aug. 29-Sept. 1, 1988). IEEE, New York, 1988, pp. 431-444.

3. BEERI, C., ET AL. A concurrency control theory for nested transactions. In Proceedings of the 2nd Annual ACM Symposium on Principles of Distributed Computing (Montreal, Aug. 17-19, 1983). ACM, New York, 1983, pp. 45-62.

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 34: Local Atomicity Properties: Modular Concurrency Control

282 l William E. Weihl

4. BERNSTEIN, P. A., AND GOODMAN, N. Concurrency control in distributed database systems. ACM Comput. Suru. 13, 2 (June 1981), 185-221.

5. BERNSTEIN, P. A., AND GOODMAN, N. Multiversion concurrency control-Theory and algo- rithms. ACM Trans. Database Syst. 8, 4 (Dec. 1983), 465-483.

6. BERNSTEIN, P., GOODMAN, N., AND LAI, M.-Y. Analyzing concurrency control when user and system operations differ. IEEE Trans. Softw. Eng. SE-9, 3 (May 1983), 223-239.

7. CAREY, M. J., AND MUHANNA, W. A. The performance of multi-version concurrency control algorithms. Tech. Rep. 550, Computer Science Dept., Univ. of Wisconsin at Madison, Aug. 1984.

8. CHAN, A., AND GRAY, R. Implementing distributed read-only transactions. IEEE Trans. Softw. Eng. SE-11, 2 (Feb. 1985), 205-212.

9. DAVIES, C. T. Recovery semantics for a DB/DC system. In Proceedings of the ACM Annual Conference (Atlanta, Ga., Aug. 27-29, 1973). ACM, New York, 19’73, pp. 136-141.

10. DAVIES, C. T. Data processing spheres of control. IBM Syst. J. 17, 2 (1978), 179-198. 11. DUBOURDIEU, D. J. Implementation of distributed transactions. In Proceedings of the 6th

Berkeley Workshop on Distributed Data Management and Computer Networks. (Berkeley, Calif., Feb. 16-19, 1982). Lawrence Berkeley Lab., Univ. of California, Berkeley, 1982, pp. 81-94.

12. ESWARAN, K. P., GRAY, J. N., LORIE, R. A., AND TRAIGER, I. L. The notions of consistency and predicate locks in a database system. Commun. ACM 19, 11 (Nov. 1976), 624-633.

13. FEKETE, A., LYNCH, N., MERRIT, M., AND WEIHL, W. Commutativity-based locking for nested transactions. Tech. Rep. MIT-LCS TM-370, Dept. of Computer Science, Massachusetts Institute of Technology, Cambridge, Mass.. 1988.

14. GRAY, J. Notes on database operating systems. In Operating Systems-An Adunnced Course. Lecture Notes in Computer Science, vol. 60. Springer-Verlag, New York, 1978, pp. 393-481.

15. HADZILACOS, V. A theory of reliability in database systems. J. ACM 35, 1 (Jan. 1988), 121-145. 16. HERLIHY, M. P. Comparing how atomicity mechanisms support replication. In Proceedings of

the 4th Annual ACM Symposium on Principles of Distributed Computing (Minaki, Canada, Aug. 5-7,1985). ACM, New York, 1985, pp. 102-110.

17. HERLIHY, M. P. Optimistic concurrency control for abstract data types. In Fifth ACMSZGACT- SZGOPS Symposium on Principles of Distributed Computing (Aug. ll-13,1986). ACM, New York, 1986, pp. 206-217.

18. HERLIHY, M. P. Extending multiversion timestamping protocols to exploit type information. Special issue on parallel and distributed computing. IEEE Trans. Comput. C-36, 4 (Apr. 1987).

19. HERLIHY, M., AND WEIHL, W. Hybrid concurrency control for abstract data types. In Proceed- ings of the ACM Symposium on Principles of Database Systems (Austin, Tex., Mar. 21-23, 1988). ACM, New York, 1988, pp. 201-210.

20. HERLIHY, M. P., LYNCH, N., MERRITT, M., AND WEIHL, W. On the correctness of orphan elimination algorithms. J. ACM. To be published. (Also available as MIT/LCS/TM-329. A preliminary version was published in the Seuenteenth International Symposium on Fault-Tolerant Computing in 1987.)

21. KORTH, H. F. Locking protocols: General lock classes and deadlock freedom. Ph.D. thesis, Dept. of Computer Science, Princeton Univ., Princeton, N.J., 1981.

22. KUNG, H. T., AND PAPADIMITRIOU, C. H. An optimality theory of concurrency control for databases. Acta Znf. 19, 1 (Apr. 1983), l-11.

23. KUNG, H. T., AND ROBINSON, ,J. T. On optimistic methods for concurrency control. ACM Trans. Database Syst. 6, 2 (June 1981), 213-226.

24. LAMPORT, L. Time, clocks and the ordering of events in a distributed system. Commun. ACM 22, 7 (July 1978), 558-565.

25. LAMPSON, B. Atomic transactions. In Distributed Systems: Architecture and Implementation, Lecture Notes in Computer Science, vol. 105, E. Goos and J. Hartmanis, Eds. Springer-Verlag, Berlin, 1981, pp. 246-265.

26. LISKOV, B., AND SCHEIFLER, R. Guardians and actions: Linguistic support for robust, distrib- uted programs. ACM Trans. Program. Lang. Syst. 5, 3 (July 1983), 381-404.

27. LISKOV, B., AND WEIHL, W. Specifications of distributed programs. D&rib. Comput. I, 2 (1986), 102-118.

28. LISKOV, B., AND ZILLES, S. N. Programming with abstract data types. In Proceedings of the ACM-SZGPLAN Conference on Very High Level Languages. ACM SZGPLAN Not. 9, 4 (Apr. 1974), 50-59.

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.

Page 35: Local Atomicity Properties: Modular Concurrency Control

Local Atomicity Properties - 283

29. LISKOV, B., SCHEIFLER, R., WALKER, E. F., AND WEIHL, W. Orphan detection (extended abstract). In Proceedings of the 17th International Symposium on Fault-Tolerant Computing (Pittsburgh, Pa., July 6-8, 1987). IEEE, New York, 1987, pp. 2-7.

30. LYNCH, N. A. Concurrency control for resilient nested transactions. In Proceedings of the 2nd ACM Symposium on Principles of Database Systems (Atlanta, Ga., Mar. 21-23, 1983). ACM, New York, 1983, pp. 166-181. (Revised version to appear in Adu. Comput. Res.)

31. LYNCH, N. A., MERRITT, M., WEIHL, W., AND FEKETE, A. A theory of atomic transactions. Tech. Rep. MIT-LCS-TM-362, Dept. of Computer Science, Massachusetts Institute of Technol- ogy, Cambridge, Mass., 1988. (Also appeared in the Proceedings of the 1988 International Conference on Database Theory.)

32.. MOSS, J. E. B. Nested transactions: An approach to reliable distributed computing. Ph.D. thesis, Dept. of Computer Science, Massachusetts Institute of Technology, Cambridge, Mass., 1981. (Also available as Tech. Rep. MIT/LCS/TR-260.)

33. PAPADIMITRIOU, C. H. The serializability of concurrent database updates. J. ACM 26, 4 (Oct. 1979), 631-653.

34. PAPADIMITRIOU, C. H., AND KANELLAKIS, P. On concurrency control by multiple versions. ACM Trans. Database Syst. 9, 1 (Mar. 1984), 89-99.

35. Pu, C. Superdatabases for composition of heterogeneous databases. In Proceedings of the 4th Data Engineering Conference (Los Angeles, Calif., Feb. l-5, 1988). IEEE, New York, 1988, pp. 548-555. (Also available as Tech. Rep. CUCS-243-86, Columbia Univ., Dept. of Computer Science).

36. REED, D. P. Naming and synchronization in a decentralized computer system. Ph.D. thesis, Dept. of Computer Science, Massachusetts Institute of Technology, Cambridge, Mass., 1978. (Also available as Tech. Rep. MIT/LCS/TR-205.)

37. SCHWARZ, P., AND SPECTOR, A. Synchronizing shared abstract types. ACM Trans. Comput. Syst. 2,3 (Aug. 1984), 223-250.

38. SILBERSCHATZ, A., AND KEDEM, Z. Consistency in hierarchical database systems. J. ACM 27, 1 (Jan. 1980), 72-80.

39. SILBERSCHATZ, A., AND KEDEM, Z. A family of locking protocols for database systems that are modeled by directed graphs. IEEE Trans. Softw. Eng. 8, 6 (Nov. 1982), 558-562.

40. SKEEN, M. D. Crash recovery in a distributed database system. Ph.D. thesis, Dept. of Computer Science, Univ. of California at Berkeley, May 1982. (Also avaiiable as UCB/ERL M82/45.)

41. WEIHL, W. E. Data-dependent concurrency control and recovery. In Proceedings of the 2nd Annual ACM Symposium on Principles of Distributed Computing (Montreal, Aug. 17-19, 1983). ACM, New York, 1983, pp. 63-75.

42. WEIHL, W. E. Specification and implementation of atomic data types. Ph.D. thesis, Dept. of Computer Science, Massachusetts Institute of Technology, Cambridge, Mass., 1984. (Also avail- able as Tech. Rep. MIT/LCS/TR-314.)

43. WEIHL, W. E. Distributed version management for read-only actions. IEEE Trans. Softw. Eng. SE-13, 1 (Jan. 1987), 55-64.

44. WEIHL, W. E. Commutativity-based concurrency control for abstract data types. IEEE Trans. Comput. 37, 12 (Dec. 1988), 1488-1505. (Also available as Tech. Rep. MIT/LCS/TM-367.)

45. WEIHL, W. E. The impact of recovery on concurrency control. In Proceedings of the ACM Symposium on Principles of Database Systems (Philadelphia, Pa., Mar. 29-31, 1989). ACM, New York, 1989.

46. WEIHL, W., AND LISKOV, B. Implementation of resilient, atomic data types. ACM Trans. Program. Lang. Syst. 17,2 (Apr. 1985), 244-269.

Received July 1986; revised September 1988; accepted January 1989

ACM Transactions on Programming Languages and Systems, Vol. 11, No. 2, April 1989.