We have so far been quiet about the
specific benefits that
STM gives us.
Most obvious is how well it composes—to add code to
a transaction, we just use our usual monadic building blocks,
The notion of composability is critical to building
modular software. If we take two pieces of code that work correctly
individually, the composition of the two should also be correct. While
normal threaded programming makes composability impossible,
STM restores it as a key assumption that we
can rely upon.
The STM monad prevents us from
accidentally performing nontransactional I/O actions. We don’t need to
worry about lock ordering, since our code contains no locks. We can
forget about lost wakeups, since we don’t have condition variables. If
an exception is thrown, we can either catch it using
catchSTM or be bounced out of our
transaction, leaving our state untouched. Finally, the
orElse functions give us some beautiful ways
to structure our code.
Code that uses
STM will not deadlock, but it is possible for
threads to starve each other to some degree. A long-running transaction
can cause another transaction to
retry often enough that it will make
comparatively little progress. To address a problem such as this, make
your transactions as short as you can, while keeping your data
Whether with concurrency or memory management, there will be times when we must retain control: some software must make ...