diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -7,11 +7,32 @@
 *de facto* standard Haskell versioning scheme.
 
 
-1.1.2.1 [2017-06-07] (tag: [concurrency-1.1.2.1][])
+1.2.0.0
 -------
 
-https://hackage.haskell.org/package/concurrency-1.1.2.1
+- **Date**    2017-09-16
+- **Git tag** [concurrency-1.2.0.0][]
+- **Hackage** https://hackage.haskell.org/package/concurrency-1.2.0.0
 
+### Control.Monad.STM.Class
+
+- `MonadSTM` now has a `MonadPlus` constraint.
+- The `orElse` and `retry` functions have been promoted to top-level definitions, and are aliases
+  for `mplus` and `mzero`.
+
+[concurrency-1.2.0.0]: https://github.com/barrucadu/dejafu/releases/tag/concurrency-1.2.0.0
+
+
+---------------------------------------------------------------------------------------------------
+
+
+1.1.2.1
+-------
+
+- **Date**    2017-06-07
+- **Git tag** [concurrency-1.1.2.1][]
+- **Hackage** https://hackage.haskell.org/package/concurrency-1.1.2.1
+
 ### Changed
 
 - The `isEmptyMVar` function is now implemented using `tryReadMVar` instead of a combination of
@@ -28,10 +49,12 @@
 ---------------------------------------------------------------------------------------------------
 
 
-1.1.2.0 [2017-04-05] (tag: [concurrency-1.1.2.0][])
+1.1.2.0
 -------
 
-https://hackage.haskell.org/package/concurrency-1.1.2.0
+- **Date**    2017-04-05
+- **Git tag** [concurrency-1.1.2.0][]
+- **Hackage** https://hackage.haskell.org/package/concurrency-1.1.2.0
 
 ### Control.Concurrent.Classy.Async
 
@@ -66,10 +89,12 @@
 ---------------------------------------------------------------------------------------------------
 
 
-1.1.1.0 [2017-03-04] (git tag: [concurrency-1.1.1.0][])
+1.1.1.0
 -------
 
-https://hackage.haskell.org/package/concurrency-1.1.1.0
+- **Date**    2017-03-04
+- **Git tag** [concurrency-1.1.1.0][]
+- **Hackage** https://hackage.haskell.org/package/concurrency-1.1.1.0
 
 ### Miscellaneous
 
@@ -82,10 +107,12 @@
 ---------------------------------------------------------------------------------------------------
 
 
-1.1.0.0 [2017-02-21] (git tag: [concurrency-1.1.0.0][])
+1.1.0.0
 -------
 
-https://hackage.haskell.org/package/concurrency-1.1.0.0
+- **Date**    2017-02-21
+- **Git tag** [concurrency-1.1.0.0][]
+- **Hackage** https://hackage.haskell.org/package/concurrency-1.1.0.0
 
 ### Control.Monad.Conc.Class
 
@@ -100,10 +127,12 @@
 ---------------------------------------------------------------------------------------------------
 
 
-1.0.0.0 [2016-09-10] (git tag: [concurrency-1.0.0.0][])
+1.0.0.0
 -------
 
-https://hackage.haskell.org/package/concurrency-1.0.0.0
+- **Date**    2016-09-10
+- **Git tag** [concurrency-1.0.0.0][]
+- **Hackage** https://hackage.haskell.org/package/concurrency-1.0.0.0
 
 Initial release. Go read the API docs.
 
diff --git a/Control/Monad/STM/Class.hs b/Control/Monad/STM/Class.hs
--- a/Control/Monad/STM/Class.hs
+++ b/Control/Monad/STM/Class.hs
@@ -17,22 +17,21 @@
 -- import "Control.Concurrent.Classy.STM" (which exports
 -- "Control.Monad.STM.Class").
 --
--- __Deviations:__ An instance of @MonadSTM@ is not required to be an
--- @Alternative@, @MonadPlus@, and @MonadFix@, unlike @STM@. The
--- @always@ and @alwaysSucceeds@ functions are not provided; if you
--- need these file an issue and I'll look into it.
+-- __Deviations:__ An instance of @MonadSTM@ is not required to be a
+-- @MonadFix@, unlike @STM@. The @always@ and @alwaysSucceeds@
+-- functions are not provided; if you need these file an issue and
+-- I'll look into it.
 module Control.Monad.STM.Class
   ( MonadSTM(..)
+  , retry
   , check
+  , orElse
   , throwSTM
   , catchSTM
-
-  -- * Utilities for instance writers
-  , liftedOrElse
   ) where
 
 import           Control.Exception            (Exception)
-import           Control.Monad                (unless)
+import           Control.Monad                (MonadPlus(..), unless)
 import           Control.Monad.Reader         (ReaderT)
 import           Control.Monad.Trans          (lift)
 import           Control.Monad.Trans.Control  (MonadTransControl, StT, liftWith)
@@ -53,12 +52,10 @@
 -- each 'MonadConc' has an associated @MonadSTM@ from which it can
 -- atomically run a transaction.
 --
--- @since 1.0.0.0
-class Ca.MonadCatch stm => MonadSTM stm where
+-- @since 1.2.0.0
+class (Ca.MonadCatch stm, MonadPlus stm) => MonadSTM stm where
   {-# MINIMAL
-        retry
-      , orElse
-      , (newTVar | newTVarN)
+        (newTVar | newTVarN)
       , readTVar
       , writeTVar
     #-}
@@ -70,22 +67,6 @@
   -- @since 1.0.0.0
   type TVar stm :: * -> *
 
-  -- | Retry execution of this transaction because it has seen values
-  -- in @TVar@s that it shouldn't have. This will result in the
-  -- thread running the transaction being blocked until any @TVar@s
-  -- referenced in it have been mutated.
-  --
-  -- @since 1.0.0.0
-  retry :: stm a
-
-  -- | Run the first transaction and, if it @retry@s, run the second
-  -- instead. If the monad is an instance of
-  -- 'Alternative'/'MonadPlus', 'orElse' should be the '(<|>)'/'mplus'
-  -- function.
-  --
-  -- @since 1.0.0.0
-  orElse :: stm a -> stm a -> stm a
-
   -- | Create a new @TVar@ containing the given value.
   --
   -- > newTVar = newTVarN ""
@@ -118,12 +99,32 @@
   -- @since 1.0.0.0
   writeTVar :: TVar stm a -> a -> stm ()
 
+-- | Retry execution of this transaction because it has seen values in
+-- @TVar@s that it shouldn't have. This will result in the thread
+-- running the transaction being blocked until any @TVar@s referenced
+-- in it have been mutated.
+--
+-- This is just 'mzero'.
+--
+-- @since 1.2.0.0
+retry :: MonadSTM stm => stm a
+retry = mzero
+
 -- | Check whether a condition is true and, if not, call @retry@.
 --
 -- @since 1.0.0.0
 check :: MonadSTM stm => Bool -> stm ()
 check b = unless b retry
 
+-- | Run the first transaction and, if it @retry@s, run the second
+-- instead.
+--
+-- This is just 'mplus'.
+--
+-- @since 1.2.0.0
+orElse :: MonadSTM stm => stm a -> stm a -> stm a
+orElse = mplus
+
 -- | Throw an exception. This aborts the transaction and propagates
 -- the exception.
 --
@@ -141,8 +142,6 @@
 instance MonadSTM STM.STM where
   type TVar STM.STM = STM.TVar
 
-  retry     = STM.retry
-  orElse    = STM.orElse
   newTVar   = STM.newTVar
   readTVar  = STM.readTVar
   writeTVar = STM.writeTVar
@@ -154,8 +153,6 @@
 instance C => MonadSTM (T stm) where { \
   type TVar (T stm) = TVar stm      ; \
                                       \
-  retry       = lift retry          ; \
-  orElse      = liftedOrElse F      ; \
   newTVar     = lift . newTVar      ; \
   newTVarN n  = lift . newTVarN n   ; \
   readTVar    = lift . readTVar     ; \
@@ -186,17 +183,3 @@
 INSTANCE(RS.RWST r w s, (MonadSTM stm, Monoid w), (\(a,_,_) -> a))
 
 #undef INSTANCE
-
--------------------------------------------------------------------------------
-
--- | Given a function to remove the transformer-specific state, lift
--- an @orElse@ invocation.
---
--- @since 1.0.0.0
-liftedOrElse :: (MonadTransControl t, MonadSTM stm)
-  => (forall x. StT t x -> x)
-  -> t stm a -> t stm a -> t stm a
-liftedOrElse unst ma mb = liftWith $ \run ->
-  let ma' = unst <$> run ma
-      mb' = unst <$> run mb
-  in ma' `orElse` mb'
diff --git a/concurrency.cabal b/concurrency.cabal
--- a/concurrency.cabal
+++ b/concurrency.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                concurrency
-version:             1.1.2.1
+version:             1.2.0.0
 synopsis:            Typeclasses, functions, and data types for concurrency and STM.
 
 description:
@@ -32,7 +32,7 @@
 source-repository this
   type:     git
   location: https://github.com/barrucadu/dejafu.git
-  tag:      concurrency-1.1.2.1
+  tag:      concurrency-1.2.0.0
 
 library
   exposed-modules:     Control.Monad.Conc.Class
