not uncommon, and in fact people encounter this delay between a transaction and their running balance regularly (e.g., ATM withdrawals and cellphone calls).

How the SQL statements are modified to relax consistency depends upon how the running balances are defined. If they are simply estimates, meaning that some transactions can be missed, the changes are quite simple, as shown in figure 4.

We’ve now decoupled the updates to the user and transaction tables. Consistency between the tables is not guaranteed. In fact, a failure between the first and second transaction will result in the user table being permanently inconsistent, but if the contract stipulates that the running totals are estimates, this may be adequate.

What if estimates are not acceptable, though? How
can you still decouple the user and transaction updates?

Introducing a persistent
message queue solves the
problem. There are several
choices for implement-
ing persistent messages.
The most critical factor in
implementing the queue,
however, is ensuring that
the backing persistence is
on the same resource as the
database. This is necessary
to allow the queue to be
transactionally committed
without involving a 2PC.
Now the SQL operations
look a bit different, as
shown in figure 5.
This example takes
some liberties with syntax
and oversimplifying the
logic to illustrate the
concept. By queuing a
persistent message within
the same transaction as
the insert, the information
needed to update the run-
ning balances on the user
h as been captured. The
t ransaction is contained on
a single database instance
FIG 5 a nd therefore will not
i mpact system availability.
A separate message-
p rocessing component will

AN ACID ALTERNATIVE

are updated. Using an ACID-style transaction, the SQL would be as shown in figure 3.

The total bought and sold columns in the user table can be considered a cache of the transaction table. It is present for efficiency of the system. Given this, the constraint on consistency could be relaxed. The buyer and seller expectations can be set so their running balances do not reflect the result of a transaction immediately. This is

 

B egin transaction

Insert into transaction(id, seller_id, buyer_id, amount);

E nd transaction

B egin transaction

Update user set amt_sold=amt_sold+$amount where id=$seller_id; Update user set amt_bought=amount_bought+$amount where id=$buyer_id;

End transaction

FIG 4

Begin transaction

Insert into transaction(id, seller_id, buyer_id, amount); Queue message “update user(“seller”, seller_id, amount)”; Queue message “update user(“buyer”, buyer_id, amount)”;

End transaction

For each message in queue Begin transaction

Dequeue message

If message.balance == “seller”
Update user set amt_sold=amt_sold + message.amount
where id=message.id;
Else
Update user set amt_bought=amt_bought + message.amount
where id=message.id;
End if

End transaction

References:

mailto:feedback@acmqueue.com

Archives