Specifying Transaction Control to Serialize Concurrent Program Executions
Egon B\"orger, Klaus-Dieter Schewe

TL;DR
This paper introduces a language-independent transaction controller and operator that transform concurrent program executions into serializable transactions, ensuring correctness and broad applicability through formal specifications in Abstract State Machines.
Contribution
It defines a formal transaction controller and operator applicable to various programs, guaranteeing serializability and correctness in concurrent executions.
Findings
Proves that concurrent runs under the transaction controller are serializable.
Provides a formal specification of the transaction controller and operator.
Applicable as a plug-in for specifying concurrent system components.
Abstract
We define a programming language independent transaction controller and an operator which when applied to concurrent programs with shared locations turns their behavior with respect to some abstract termination criterion into a transactional behavior. We prove the correctness property that concurrent runs under the transaction controller are serialisable. We specify the transaction controller TaCtl and the operator TA in terms of Abstract State Machines. This makes TaCtl applicable to a wide range of programs and in particular provides the possibility to use it as a plug-in when specifying concurrent system components in terms of Abstract State Machines.
Peer Reviews
No public reviews on file for this paper yet. If you reviewed it on a platform where reviews are public (OpenReview, ICLR, NeurIPS, ICML), you can paste yours below so the community can read it here.
Videos
No videos yet. Explain this paper in a talk, walkthrough, or lecture? Add one.
\symitalic
041
\symitalic 061
11institutetext: Università di Pisa, Dipartimento di Informatica, I-56125 Pisa, Italy 11email: [email protected] 22institutetext: Software Competence Centre Hagenberg, A-4232 Hagenberg, Austria 22email: [email protected]
Specifying Transaction Control
to Serialize Concurrent Program Executions††thanks: The research reported in this paper results from the project Behavioural Theory and Logics for Distributed Adaptive Systems supported by the Austrian Science Fund (FWF): [P26452-N15].††thanks: The final publication is available at Springer via https://doi.org/10.1007/978-3-662-43652-3_13.
Egon Börger and Klaus-Dieter Schewe 1122
Abstract
We define a programming language independent transaction controller and an operator which when applied to concurrent programs with shared locations turns their behavior with respect to some abstract termination criterion into a transactional behavior. We prove the correctness property that concurrent runs under the transaction controller are serialisable. We specify the transaction controller TaCtl and the operator in terms of Abstract State Machines. This makes TaCtl applicable to a wide range of programs and in particular provides the possibility to use it as a plug-in when specifying concurrent system components in terms of Abstract State Machines.
1 Introduction
This paper is about the use of transactions as a common means to control concurrent access of programs to shared locations and to avoid that values stored at these locations are changed almost randomly. A transaction controller interacts with concurrently running programs (read: sequential components of an asynchronous system) to control whether access to a shared location can be granted or not, thus ensuring a certain form of consistency for these locations. A commonly accepted consistency criterion is that the joint behavior of all transactions (read: programs running under transactional control) with respect to the shared locations is equivalent to a serial execution of those programs. Serialisability guarantees that each transaction can be specified independently from the transaction controller, as if it had exclusive access to the shared locations.
It is expensive and cumbersome to specify transactional behavior and prove its correctness again and again for components of the great number of concurrent systems. Our goal is to define once and for all an abstract (i.e. programming language independent) transaction controller TaCtl which can simply be “plugged in” to turn the behavior of concurrent programs (read: components of any given asynchronous system ) into a transactional one. This involves to also define an operator which forces the programs to listen to the controller TaCtl when trying to access shared locations.
For the sake of generality we define the operator and the controller in terms of Abstract State Machines (ASMs) which can be read and understood as pseudo-code so that TaCtl and the operator can be applied to code written in any programming language (to be precise: whose programs come with a notion of single step, the level where our controller imposes shared memory access constraints to guarantee transactional code behavior). On the other side, the precise semantics underlying ASMs (for which we refer the reader to [5]) allows us to mathematically prove the correctness of our controller and operator.
We concentrate here on transaction controllers that employ locking strategies such as the common two-phase locking protocol (2PL). That is, each transaction first has to acquire a (read- or write-) lock for a shared location, before the access is granted. Locks are released after the transaction has successfully committed and no more access to the shared locations is necessary. There are of course other approaches to transaction handling, see e.g. [6, 14, 15, 17] and the extensive literature there covering classical transaction control for flat transactions, timestamp-based, optimistic and hybrid transaction control protocols, as well as non-flat transaction models such as sagas and multi-level transactions.
We define TaCtl and the operator in Sect. 2 and the TaCtl components in Sect. 3. In Sect. 4 we prove the correctness of these definitions.
2 The Transaction Operator )
As explained above, a transaction controller performs the lock handling, the deadlock detection and handling, the recovery mechanism (for partial recovery) and the commit of single machines. Thus we define it as consisting of four components specified in Sect. 3.
LockHandler
DeadlockHandler
Recovery
Commit
The operator transforms the components of any concurrent system (asynchronous ASM) into components of a concurrent system where each runs as transaction under the control of TaCtl:
TaCtl keeps a dynamic set of those machines whose runs it currently has to supervise to perform in a transactional manner until has its transactional behavior (so that it can Commit it).111In this paper we deliberately keep the termination criterion abstract so that it can be refined in different ways for different transaction instances. To turn the behavior of a machine into a transactional one, first of all has to register itself with the controller TaCtl, read: to be inserted into the set of currently to be handled ions. To Undo as part of a recovery some steps made already during the given transactional run segment of , a last-in first-out queue is needed which keeps track of the states the transactional run goes through; when enters the set the has to be initialized (to the empty queue).
The crucial transactional feature is that each non private (i.e. shared or monitored or output) location a machine needs to read or write for performing a step has to be for this purpose; tries to obtain such locks by calling the LockHandler. In case no are needed by in its or the needed can be by the LockHandler, performs its next step; in addition, for a possible future recovery, the machine has to Record in its the current values of those locations which are (possibly over-) written by this -step together with the obtained . Then continues its transactional behavior until it is . In case the needed are , namely because another machine in for some needed has or (in case wants a W-(rite)Lock) has , has to for ; in fact it continues its transactional behavior by calling again the LockHandler for the needed —until the needed locked locations are unlocked when ’s transactional behavior is Commited, whereafter a new request for these locks this time may be to .222As suggested by a reviewer, a refinement (in fact a desirable optimization) consists in replacing such a waiting cycle by suspending until the needed locks are released. Such a refinement can be obtained in various ways, a simple one consisting in letting simply stay in until the and refining LockHandler to only choose pairs where it can and doing nothing otherwise (i.e. defining ). See Sect. 3.
As a consequence deadlocks may occur, namely when a cycle occurs in the transitive closure of the relation. To resolve such deadlocks the DeadlockHandler component of TaCtl chooses some machines as s for a recovery.333To simplify the serializability proof in Sect.3 and without loss of generality we define a reaction of machines to their victimization only when they are in TA- (not in ). This is to guarantee that no locks are to a machine as long as it does . After a victimized machine is by the Recovery component of TaCtl, so that can exit its state, it continues its transactional behavior.
This explains the following definition of as a control state ASM, i.e. an ASM with a top level Finite State Machine control structure. We formulate it by the flowchart diagram of Fig. 1, which has a precise control state ASM semantics (see the definition in [5, Ch.2.2.6]). The components for the recovery feature are highlighted in the flowchart by a colouring that differs from that of the other components. The macros which appear in Fig. 1 and the components of TaCtl are defined below.
The predicate holds if in the current state of at least one of two cases happens:444See [5, Ch.2.2.3] for the classification of locations and functions. either to perform its step in this state reads some shared or monitored location which is not yet or writes some shared or output location which is not yet for writing. A location can be for reading () or for writing (). Formally:
555 For layout reasons we omit in Fig.1 the arguments of the functions and .
666By the second argument of (and below of ) we indicate that this function of is a dynamic function which is evaluated in each state of , namely by computing in this state the sets and ; see Sect. 4 for the detailed definition.
777By we denote the complement of .
The ues are the -values (retrieved by the -function) of those shared or output locations which are written by in its . To Record the set of these values together with the obtained means to append the pair of these two sets to the queue of from where upon recovery the values and the locks can be retrieved.
To CallLockHandler for the requested by in its means to into the LockHandler’s set of to be handled s. Similarly we let CallCommit(M) stand for insertion of into a set of the Commit component.
3 The Transaction Controller Components
A CallCommit(M) by machine enables the Commit component. Using the operator we leave the order in which the s are handled refinable by different instantiations of TaCtl.
Commiting means to Unlock all locations that are . Note that each lock obtained by remains with until the end of ’s transactional behavior. Since performs a CallCommit(M) when it has its transactional computation, nothing more has to be done to Commit besides deleting from the sets of s and still to be handled ions.888We omit clearing the queue since it is initialized when is inserted into .
Note that the locations and are shared by the Commit, LockHandler and Recovery components, but these components never have the same simultaneously in their request resp. set since when machine has performed a CallCommit(M), it has its transactional computation and does not participate any more in any or ization.
As for Commit also for the LockHandler we use the operator to leave the order in which the s are handled refinable by different instantiations of TaCtl.
The strategy we adopt for lock handling is to refuse all locks for locations requested by if at least one of the following two cases happens:
- some of the requested locations is by another transactional machine ,
- some of the requested locations is a ation that is by another transactional machine .
This definition implies that multiple transactions may simultaneoulsy have a on some location. It is specified below by the predicate .
To RefuseRequestedLocks it suffices to set the communication interface of ; this makes for each location that is and for each ation that is by some other transactional component machine .
A originates if two machines are in a cycle, otherwise stated if for some (not yet ized) machine the pair is in the transitive (not reflexive) closure of . In this case the DeadlockHandler selects for recovery a (typically minimal) subset of transactions —they are ized to , in which mode (control state) they are backtracked until they become . The selection criteria are intrinsically specific for particular transaction controllers, driving a usually rather complex selection algorithm in terms of number of conflict partners, priorities, waiting time, etc. In this paper we leave their specification for TaCtl abstract (read: refinable in different directions) by using the operator.
Also for the Recovery component we use the operator to leave the order in which the s are chosen for recovery refinable by different instantiations of TaCtl. To be a machine is backtracked by steps until is not any more, in which case it is deleted from the set of s, so that be definition it is . This happens at the latest when has become empty.
Note that in our description of the DeadlockHandler and the (partial) Recovery we deliberately left the strategy for victim seclection and Undo abstract leaving fairness considerations to be discussed elsewhere. It is clear that if always the same victim is selected for partial recovery, the same deadlocks may be created again and again. However, it is well known that fairness can be achieved by choosing an appropriate victim selection strategy.
4 Correctness Theorem
In this section we show the desired correctness property: if all monitored or shared locations of any are output or controlled locations of some other and all output locations of any are monitored or shared locations of some other (closed system assumption)999This assumption means that the environment is assumed to be one of the component machines., each run of is equivalent to a serialization of the terminating -runs, namely the -run followed by the -run etc., where is the -th machine of which performs a commit in the run. To simplify the exposition (i.e. the formulation of statement and proof of the theorem) we only consider machine steps which take place under the transaction control, in other words we abstract from any step makes before being Inserted into or after being Deleted from the set of machines which currently run under the control of TaCtl.
First of all we have to make precise what a serial multi-agent ASM run is and what equivalence of runs means in the general multi-agent ASM framework.
4.0.1 Definition of run equivalence.
Let be a (finite or infinite) run of the system . In general we may assume that TaCtl runs forever, whereas each machine running as transaction will be terminated at some time – at least after commit will only change values of non-shared and non-output locations101010It is possible that one ASM enters several times as a transaction controlled by TaCtl. However, in this case each of these registrations will be counted as a separate transaction, i.e. as different ASMs in .. For let denote the unique, consistent update set defining the transition from to . By definition of the update set is the union of the update sets of the agents executing resp. TaCtl:
[TABLE]
contains the updates defined by the ASM in state 111111We use the shorthand notation to denote ; in other words we speak about steps and updates of also when they really are done by . Mainly this is about transitions between the control states, namely TA-, , (see Fig.1), which are performed during the run of under the control of the transaction controller TaCtl. When we want to name an original update of (not one of the updates of or of the Record component) we call it a proper -update. and contains the updates by the transaction controller in this state. The sequence of update sets , , , …will be called the schedule of (for the given transactional run).
To generalise for transactional ASM runs the equivalence of transaction schedules known from database systems [6, p.621ff.] we now define two cleansing operations for ASM schedules. By the first one (i) we eliminate all (in particular unsuccessful-lock-request) computation segments which are without proper -updates; by the second one (ii) we eliminate all -steps which are related to a later step by the Recovery component:
- (i)
Delete from the schedule of each where one of the following two properties holds:
- ( contributes no update to ),
- belongs to a step of an -computation segment where in its TA- does and in its next step moves from control-state back to control state TA, because the LockHandler refused new locks by .121212Note that by eliminating this step also the corresponding LockHandler step disappears in the run.
In such computation steps makes no proper update. 2. (ii)
Repeat choosing from the schedule of a pair with later () which belong to the first resp. second of two consecutive -Recovery steps defined as follows:
- a (say -RecoveryEntry) step whereby in state moves from control-state TA- to , because it became a ,
- the next -step (say -RecoveryExit) whereby in state moves back to control state TA- because it has been .
In these two -Recovery steps makes no proper update. Delete:
- (a)
and , 2. (b)
the update from the corresponding () which in state triggered the -RecoveryEntry, 3. (c)
-updates in any update set between the considered -RecoveryEntry and -RecoveryExit step (), 4. (d)
each belonging to the -computation segment from TA- back to TA- which contains the proper -step in that is UNDOne in by the considered step; besides control state and Record updates these contain updates with where the corresponding Undo updates are , 5. (e)
the -updates in corresponding to ’s CallLockHandler step (if any: in case are needed for the proper -step in ) in state ().
The sequence with resulting from the application of the two cleansing operations as long as possible – note that confluence is obvious, so the sequence is uniquely defined – will be called the cleansed schedule of (for the given run).
Before defining the equivalence of transactional ASM runs we remark that has indeed several runs, even for the same initial state . This is due to the fact that a lot of non-determinism is involved in the definition of this ASM. First, the submachines of TaCtl are non-deterministic:
- In case several machines request conflicting locks at the same time, the LockHandler can only grant the requested locks for one of these machines.
- Commit requests are executed in random order by the Commit submachine.
- The submachine DeadlockHandler chooses a set of victims, and this selection has been deliberately left abstract.
- The Recovery submachine chooses in each step a victim , for which the last step will be undone by restoring previous values at updated locations and releasing corresponding locks.
Second, the specification of leaves deliberately open, when a machine will be started, i.e., register as a transaction in to be controlled by TaCtl. This is in line with the common view that transactions can register at any time to the transaction controller TaCtl and will remain under its control until they commit.
Definition 1
Two runs and of are equivalent iff for each the cleansed schedules and for the two runs are the same and the read locations and the values read by in and are the same.
That is, we consider runs to be equivalent, if all transactions read the same locations and see there the same values and perform the same updates in the same order disregarding waiting times and updates that are undone.
4.0.2 Definition of serializability.
Next we have to clarify our generalised notion of a serial run, for which we concentrate on committed transactions – transactions that have not yet committed can still undo their updates, so they must be left out of consideration131313Alternatively, we could concentrate on complete, infinite runs, in which only committed transactions occur, as eventually every transaction will commit – provided that fairness can be achieved.. We need a definition of the read- and write-locations of in a state , i.e. and as used in the definition of .
The definition of depends on the locking level, whether locks are provided for variables, pages, blocks, etc. To provide a definite definition, in this paper we give the definition at the level of abstraction of the locations of the underlying class of component machines (ASMs) . Refining this definition (and that of ) appropriately for other locking levels does not innvalidate the main result of this paper.
We define , where is the defining rule of the ASM , and analogously . Then we use structural induction according to the definition of ASM rules in [5, Table 2.2]. As an auxiliary concept we need to define inductively the read and write locations of terms and formulae. The definitions use an interpretation of free variables which we suppress notationally (unless otherwise stated) and assume to be given with (as environment of) the state . This allows us to write , instead of , respectively.
4.0.3 Read/Write Locations of Terms and Formulae.
For state let be the given interpretation of the variables which may occur freely (in given terms or formulae). We write for the evaluation of (a term or a formula) in state (under the given interpretation of free variables).
Note that logical variables are not locations: they cannot be written and their values are not stored in a location but in the given interpretation from where they can be retrieved.
We define for every formula because formulae are not locations one could write into. for atomic formulae has to be defined as for terms with playing the same role as a function symbol . For propositional formulae one reads the locations of their subformulae. In the inductive step for quantified formulae denotes the superuniverse of minus the Reserve set [5, Ch.2.4.4] and the extension (or modification) of where is interpreted by a domain element .
Note that the values of the logical variables are not read from a location but from the modified state environment function .
4.0.4 Read/Write Locations of ASM Rules.
ReadLoc(\alpha,S)\cup\left\{\begin{array}[]{ll}ReadLoc(r_{1},S)&\mathrel{\mathbf{if}}val_{S}(\alpha)=true\\ ReadLoc(r_{2},S)&\mathrel{\mathbf{else}}\end{array}\right.{}
WriteLoc(\mathrel{\mathbf{if}}\alpha\mathrel{\mathbf{then}}r_{1}\mathrel{\mathbf{else}}r_{2},S)=\left\{\begin{array}[]{ll}WriteLoc(r_{1},S)&\mathrel{\mathbf{if}}val_{S}(\alpha)=true\\ WriteLoc(r_{2},S)&\mathrel{\mathbf{else}}\end{array}\right.{}
In the following cases the same scheme applies to read and write locations:141414In denotes the update set produced by rule in state under .
\left\{\begin{array}[]{ll}Read[Write]Loc(r_{2},S+U,I)&\mathrel{\mathbf{if}}yields(r_{1},S,I,U)\mathrel{\mathbf{and}}Consistent(U)\\ \emptyset&\mathrel{\mathbf{else}}\end{array}\right.
For rules we have to define the read and write locations simultaneously to guarantee that the same instance satisfying the selection condition is chosen for defining the read and write locations of the rule body :
We say that has or is committed (in state , denoted ) if step has been performed (in state ).
Definition 2
A run of is serial iff there is a total order on such that the following two conditions are satisfied:
- (i)
If in a state has committed, but has not, then holds. 2. (ii)
If has committed in state and holds, then the cleansed schedule , of satisfies .
That is, in a serial run all committed transactions are executed in a total order and are followed by the updates of transactions that did not yet commit.
Definition 3
A run of is serialisable iff it is equivalent to a serial run of .151515Modulo the fact that ASM steps permit simultaneous updates of multiple locations, this definition of serializability is equivalent to Lamport’s sequential consistency concept [16].
Theorem 4.1
Each run of is serialisable.
Proof
Let be a run of . To construct an equivalent serial run let be a machine that commits first in this run, i.e. holds for some and whenever holds for some , then holds. If there is more than one machine with this property, we randomly choose one of them.
Take the run of starting in state , say . As commits, this run is finite. has been Deleted from and none of the TaCtl components is triggered any more: neither Commit nor LockHandler because resp. remain empty; not DeadlockHandler because remains false since never s for any machine; not Recovery because remains empty. Note that in this run the schedule for is already cleansed.
We now define a run (of , as has to be shown) which starts in the final state of the run and where we remove from the run defined by the cleansed schedules for the originally given run all updates made by steps of and all updates in TaCtl steps which concern . Let
[TABLE]
That is, in the update set all updates are removed from the original run which are done by —their effect is reflected already in the initial run segment from to —or are LockHandler updates involving a or are updates of the DeadlockHandler or are updates involving a step or are done by a step involving a .
Lemma 1
* is a run of .*
Lemma 2
The run of is equivalent to the original run .
By induction hypothesis is serialisable, so and thereby also is serialisable with for all .
Proof
(Lemma 1) We first show that omitting in every update from which concerns does not affect updates by TaCtl in concerning . In fact starting in the final -state , makes no move with a update and no move of or or
It remains to show that every -step defined by is a possible -step in a run starting in . Since the considered -schedule is cleansed, we only have to consider any proper update step of in state (together with its preceding lock request step, if any). If in uses , in the run by the cleansed schedules for the original run the locks must have been granted after the first Commit, which is done for before . Thus these locks are granted also in as part of a run step. If no are needed, that proper -step depends only on steps computed after and thus is part of a run step.
Proof
(Lemma 2) The cleansed machine schedules in the two runs, the read locations and the values read there have to be shown to be the same. First consider any . Since in the initial segment no such makes any move so that its update sets in this computation segment are empty, in the cleansed schedule of for the run all these empty update sets disappear. Thus this cleansed schedule is the same as the cleansed schedule of for the run and therefore by definition of also for the original run with same read locations and same values read there.
Now consider , its schedule for the run and the corresponding cleansed schedule . We proceed by induction on the cleansed schedule steps of . When makes its first step using the -updates, this can only be a proper -step together with the corresponding Record updates (or a lock request directly preceding such a -step) because in the computation with cleansed schedule each lock request of is granted and is not ized. The values reads or writes in this step (in private or locked locations) have not been affected by a preceding step of any —otherwise would have locked before the non-private locations and keep the locks until it commits (since cleansed schedules are without Undo steps), preventing from getting these locks which contradicts the fact that is the first machine to commit and thus the first one to get the locks. Therefore the values reads or writes in the step defined by (resp. also ) coincide with the corresponding location values in the first (resp. also second) step of following the cleansed schedule to pass from to (case without request of ) resp. from to to (otherwise). The same argument applies in the inductive step which establishes the claim.
5 Conclusion
In this article we specified (in terms of Abstract State Machines) a transaction controller TaCtl and a transaction operator which turn the behaviour of a set of concurrent programs into a transactional one under the control of TaCtl. In this way the locations shared by the programs are accessed in a well-defined manner. For this we proved that all concurrent transactional runs are serialisable.
The relevance of the transaction operator is that it permits to concentrate on the specification of program behavior ignoring any problems resulting from the use of shared locations. That is, specifications can be written in a way that shared locations are treated as if they were exclusively used by a single program. This is valuable for numerous applications, as shared locations (in particular, locations in a database) are common, and random access to them is hardly ever permitted.
Furthermore, by shifting transaction control into the rigorous framework of Abstract State Machines we made several extensions to transaction control as known from the area of databases [6]. In the classical theory schedules are sequences containing read- and write-operations of the transactions plus the corresponding read- and write-lock and commit events, i.e., only one such operation or event is treated at a time. In our case we exploited the inherent parallelism in ASM runs, so we always considered an arbitrary update set with usually many updates at the same time. Under these circumstances we generalised the notion of schedule and serialisability in terms of the synchronous parallelism of ASMs. In this way we stimulate also more parallelism in transactional systems.
Among further work we would like to be undertaken is to provide a (proven to be correct) implementation of our transaction controller and the operator, in particular as plug-in for the CoreASM [8, 7] or Asmeta [4, 10] simulation engines. We would also like to see refinements or adaptations of our transaction controller model for different approaches to serialisability [14], see also the ASM-based treatment of multi-level transaction control in [15]. Last but not least we would like to see further detailings of our correctness proof to a mechanically verified one, e.g. using the ASM theories developed in KIV (see [1] for an extensive list of relevant publications) and PVS [9, 13, 12] or the (Event-)B [2, 3] theorem prover for an (Event-)B transformation of (as suggested in [11]).
5.0.1 Acknowledgement.
We thank Andrea Canciani and some of our referees for useful comments to improve the paper.
The reference list from the paper itself. Each links out to its DOI / PubMed record.
- 1[1] The KIV system. http://www.informatik.uni-augsburg.de/lehrstuehle/swt/se/kiv/.
- 2[2] J.-R. Abrial. The B-Book . Cambridge University Press, Cambridge, 1996.
- 3[3] J.-R. Abrial. Modeling in Event-B . Cambridge University Press, 2010.
- 4[4] P. Arcaini, A. Gargantini, E. Riccobene, and P. Scandurra. A model-driven process for engineering a toolset for a formal method. Software, Practice and Experience , 41(2):155–166, 2011.
- 5[5] E. Börger and R. F. Stärk. Abstract State Machines. A Method for High-Level System Design and Analysis . Springer, 2003.
- 6[6] R. Elmasri and S. B. Navathe. Fundamentals of Database Systems . Addison Wesley, 2006.
- 7[7] R. Farahbod, V. Gervasi, and U. Glässer. Core ASM: An extensible ASM execution engine. Fundamenta Informaticae , 77(1-2):71–103, 2007.
- 8[8] R. Farahbod, V. Gervasi, and U. Glässer. Executable formal specifications of complex distributed systems with Core ASM. Science of Computer Programming , 79:23–38, 2014.
