2. The transaction concept
DEBIT_CREDIT:
BEGIN_TRANSACTION;
GET
MESSAGE;
EXTRACT
ACCOUT_NUMBER,
DELTA,
TELLER,
BRANCH
FROM
MESSAGE;
FIND
ACCOUNT(ACCOUT_NUMBER)
IN
DATA
BASE;
IF
NOT_FOUND
|
ACCOUNT_BALANCE
+
DELTA
<
0
THEN
PUT
NEGATIVE
RESPONSE;
ELSE
DO;
ACCOUNT_BALANCE
=
ACCOUNT_BALANCE
+
DELTA;
POST
HISTORY
RECORD
ON
ACCOUNT
(DELTA);
CASH_DRAWER(TELLER)
=
CASH_DRAWER(TELLER)
+
DELTA;
BRANCH_BALANCE(BRANCH)
=
BRANCH_BALANCE(BRANCH)
+
DELTA;
PUT
MESSAGE
('NEW
BALANCE
='
ACCOUNT_BALANCE);
END;
COMMIT;
3. The transaction concept
DEBIT_CREDIT:
BEGIN_TRANSACTION;
GET
MESSAGE;
EXTRACT
ACCOUT_NUMBER,
DELTA,
TELLER,
BRANCH
FROM
MESSAGE;
FIND
ACCOUNT(ACCOUT_NUMBER)
IN
DATA
BASE;
IF
NOT_FOUND
|
ACCOUNT_BALANCE
+
DELTA
<
0
THEN
PUT
NEGATIVE
RESPONSE;
ELSE
DO;
ACCOUNT_BALANCE
=
ACCOUNT_BALANCE
+
DELTA;
POST
HISTORY
RECORD
ON
ACCOUNT
(DELTA);
CASH_DRAWER(TELLER)
=
CASH_DRAWER(TELLER)
+
DELTA;
BRANCH_BALANCE(BRANCH)
=
BRANCH_BALANCE(BRANCH)
+
DELTA;
PUT
MESSAGE
('NEW
BALANCE
='
ACCOUNT_BALANCE);
END;
COMMIT;
13. Distributed consistency:
staying relevant
• Is this an important problem?
• Is academia disconnected from reality?
• OK, what now?
Goal: help programmers write correct applications.
Today: some promising approaches
14. Case study: a graph
T1
T2
T4
T10
T3
T6
T5
T9
T7
T8
T11
T12
T13
T14
33. Language-level consistency
DSLs for distributed programming?
• Capture consistency concerns in the
type system
Storage
Object
Flow
Language
Application
40. Remember
• Consistency is an application-level property
• Correctness and performance are compatible
• Meet programmers on their home turf
• Build bridges!
2 things happened: academia ran down the stack, creating new I/O-level models with no accompanying intuitive contract for apps.Industry ran up the stack, developing best practices for app-level consistency without support (or guarantees!) from infrastructure
Recover common ground with programmers that was lost with the abandonment of xacts
To guard against failures, we replicate.NB: asynchrony => replicas might not agree
Very similar looking criteria (1 safe 1 live). Takes some work, even on a single site. But hard in our scenario: disorder => replica disagreement, partial failure => missing partitions
recall “the developer’s conundrum.” essentially 3 choices: 1) SC, meaningful at app level,
Ie, reorderability, batchability, tolerance to duplication / retryNow programmer must map from application invariants to object API (with richer semantics than read/write).
All API calls to add() commute; no CC necessaryApproach: adjacency lists as setsHowever, not sufficient to synchronize GC.
However, not sufficient to synchronize GC.Perhaps more importantly, not *compositional* -- what guarantees does my app – pieced together from many convergent objects – give?To reason compositionally, need guarantees about what comes OUT of my objects, and how it transits the app.
We are interested in the properties of component *outputs* rather than just internal state. Hence we are interested in a different property: confluence.A confluent module behaves like a function from sets (of inputs) to sets (of outputs)
Confluence is compositional: Composing confluent components yields a confluent dataflow
All of these components are confluent! Composing confluent components yields a confluent dataflowBut annotations are burdensome
M – a semantic property of code – implies confluenceAn appropriately constrained language provides a conservative syntactic test for M.
M – a semantic property of code – implies confluenceAn appropriately constrained language provides a conservative syntactic test for M.
Also note that a data-centric language give us the dataflow graph automatically, via dependencies (across LOC, modules, processes, nodes, etc)
Consistency models and mechanisms are only useful if they help programmers write correct applications.