My reservation caused a cascading set of effects that I don’t see. Indeed, telling me about them would
truly be TMI, causing me a great deal
of confusion. Furthermore, these
side effects persist even if my initial
work is canceled.

Side effects persist even if the stimulating activity is canceled or aborted.

˲ Record X is inserted by the user at
the record-oriented layer of abstraction as a part of transaction T1.

˲ The database system calls its B-tree manager, which climbs down the
B-tree to insert Record X. Upon discovering that the leaf of the B-tree is too
full to receive Record X, it splits the leaf
into two and stores Record X in one of
them.

˲ Transaction T1 does some more
stuff.

˲ Transaction T1 is aborted at the record-oriented layer. As a consequence,
the B-tree manager is called to delete
Record X from the B-tree, which it
does. The split of the leaf of the B-tree is
not undone.

When transaction T1 is aborted, all
effects of T1 are eliminated from the
set of records making up the database.
Still, the leaf of the B-tree has been split
and remains split. The accompanying
figure shows layered abstractions with
database records on top and B-tree
implementations below. A database
transaction inserts into a B-tree, causing a block splt. Later, the database
transaction aborts, causing a delete to
the B-tree. While Record X is deleted
from the B-tree, the block split is not
necessarily undone.

The record-oriented database is correct with T1 removed. The B-tree as a
B-tree is correct with the proper leaves,
indices, and pointers. Still, the B-tree
is different because the transaction inserted and later deleted Record X.

The split of the B-tree is a side effect
of the aborted transaction T1. From
the perspective of the set of records in
the database, that’s TMI.

Idempotence and Side Effects

Personally, I think all distributed com-puting depends on timeouts, retries,and idempotence. 3 Idempotence is theproperty of certain operations thatyou can do more than once but get thesame result as if you did it once. Time-outs, retries, and idempotence allowthe distribution of work with very highprobabilities of success.

Now, what does idempotence mean
if there are side effects? Is an operation
idempotent if it causes monitoring of
the call? That yields two monitoring
records and is, hence, not an identical
result. An operation is idempotent if it
is repeatable at the desired layer of abstraction. It is typically considered OK
if logging and monitoring record both
attempts.

Idempotence is in the eye of the
beholder.

Side effects to an idempotent operation are always OK. After all, they are
side effects and, hence, not semantically important.

I’ll Get Around to Hysteresis

It is quite common for one layer of
the system to be slow in undoing
stuff it recently did. This avoids the
overall system flopping and jittering
too aggressively.

For example, when the hotel reservation is canceled because I chose
not to go to Europe, it probably didn’t
change the order for groceries. Perhaps my reservation pushed the occupancy to 200 rooms and a new level of
demand for the restaurant. Most likely,
the expected occupancy will need to
drop to 180 or so before the hotel will
fiddle with the grocery order. Repeatedly calling the grocer to schedule,
then cancel, then schedule deliveries is
likely to drive the grocer to remove the
hotel from its list of customers.

Similarly, most B-tree managers
are not anxious to merge two adjacent
blocks when they fall below 50% each.
The cost of rejiggering their contents
repeatedly is too high.

Side effects from canceled work will
sometimes leave the system in a different state from what it was before.
That may, in turn, impact subsequent
requests.

Conclusion

Our systems compose in fascinating
ways that have interesting interactions.

To cope with this, many times we needto ignore the complications inside ofthe systems we use and just pretend lifeis simpler than it really is. That’s great!We live in a higher level of abstractionand don’t sweat the details.

One system’s side effect is another’s
meat and potatoes.

Still, the system providing the lower
level of abstraction sees its job as its
reason for existence. An order of groceries is the main purpose of the res-taurant-scheduling application. Similarly, the B-tree manager has to keep
records, fit them into the B-tree, and
split when necessary. That’s not a side
effect but rather part of the job.

Side effects are only side effects to
busybodies not minding their own
business!

Just Look Past the TMI

If every system pays attention to its
own layer of abstraction and ignores
the TMI of other layers of abstraction,
all of this composition makes sense.
Good design involves knowing when
stuff is relevant and when stuff is TMI.
After all, your Great Uncle’s digestive
problems are relevant to his doctor!

Pat Helland has been implementing transaction systems,
databases, application platforms, distributed systems,
fault-tolerant systems, and messaging systems since
1978. He currently works at Salesforce.

Copyright held by owner/author.
Publication rights licensed to ACM. $15.00.