diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
 # Change log
 
+## 0.2.0.0
+
+* Updated for postgresql-tx-0.2.0.0.
+* Added `HasCallStack` constraints in transaction runners.
+* Added more transaction runners: `pgWithTransactionSerializable`, `pgWithTransactionModeRetry`.
+* Added `pgWithSavepoint`.
+* Added `pgQueryWithMasker`, `pgExecuteWithMasker`.
+* Moved internals to an `Internal` module.
+
 ## 0.1.0.0
 
-Initial release
+* Initial release
diff --git a/package.yaml b/package.yaml
--- a/package.yaml
+++ b/package.yaml
@@ -1,6 +1,6 @@
 name:                postgresql-tx-query
-version:             0.1.0.0
-github:              "simspace/postgresql-tx/query"
+version:             0.2.0.0
+github:              "simspace/postgresql-tx"
 license:             BSD3
 license-file:        LICENSE.md
 author:              "Cary Robbins"
@@ -20,13 +20,17 @@
 
 dependencies:
 - base >= 4.7 && < 5
+- exceptions >= 0.10.4 && < 0.11
+- monad-control >= 1.0.2.3 && < 1.1
 - monad-logger >= 0.3.32 && < 0.4
 - mtl >= 2.2.2 && < 2.3
 - postgresql-query >= 3.5.0 && < 3.6
 - postgresql-simple >= 0.6.2 && < 0.7
-- postgresql-tx >= 0.1.0.0 && < 0.2
-- postgresql-tx-monad-logger >= 0.1.0.0 && < 0.2
+- postgresql-tx >= 0.2.0.0 && < 0.3
+- postgresql-tx-monad-logger >= 0.2.0.0 && < 0.3
+- postgresql-tx-simple >= 0.2.0.0 && < 0.3
 - transformers >= 0.5.6.2 && < 0.6
+- transformers-base >= 0.4.5.2 && < 0.5
 
 library:
   source-dirs: src
diff --git a/postgresql-tx-query.cabal b/postgresql-tx-query.cabal
--- a/postgresql-tx-query.cabal
+++ b/postgresql-tx-query.cabal
@@ -1,13 +1,13 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.33.0.
+-- This file has been generated from package.yaml by hpack version 0.31.2.
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 6e3ca7ec1f2e454d1e99e74cb23491feeec03749caaa5915dd4ab56d4196f856
+-- hash: de75a082fc842191537ebebf90b7cab40f5bc05129aa56df357a75d3f0928172
 
 name:           postgresql-tx-query
-version:        0.1.0.0
+version:        0.2.0.0
 synopsis:       postgresql-tx interfacing for use with postgresql-query.
 description:    Please see the README on GitHub at <https://github.com/simspace/postgresql-tx#readme>
 category:       Database
@@ -27,11 +27,11 @@
 source-repository head
   type: git
   location: https://github.com/simspace/postgresql-tx
-  subdir: query
 
 library
   exposed-modules:
       Database.PostgreSQL.Tx.Query
+      Database.PostgreSQL.Tx.Query.Internal
       Database.PostgreSQL.Tx.Query.Internal.Reexport
   other-modules:
       Paths_postgresql_tx_query
@@ -40,11 +40,15 @@
   ghc-options: -Wall
   build-depends:
       base >=4.7 && <5
+    , exceptions >=0.10.4 && <0.11
+    , monad-control >=1.0.2.3 && <1.1
     , monad-logger >=0.3.32 && <0.4
     , mtl >=2.2.2 && <2.3
     , postgresql-query >=3.5.0 && <3.6
     , postgresql-simple >=0.6.2 && <0.7
-    , postgresql-tx >=0.1.0.0 && <0.2
-    , postgresql-tx-monad-logger >=0.1.0.0 && <0.2
+    , postgresql-tx >=0.2.0.0 && <0.3
+    , postgresql-tx-monad-logger >=0.2.0.0 && <0.3
+    , postgresql-tx-simple >=0.2.0.0 && <0.3
     , transformers >=0.5.6.2 && <0.6
+    , transformers-base >=0.4.5.2 && <0.5
   default-language: Haskell2010
diff --git a/src/Database/PostgreSQL/Tx/Query.hs b/src/Database/PostgreSQL/Tx/Query.hs
--- a/src/Database/PostgreSQL/Tx/Query.hs
+++ b/src/Database/PostgreSQL/Tx/Query.hs
@@ -1,61 +1,91 @@
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE TypeSynonymInstances #-}
-{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE RankNTypes #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 module Database.PostgreSQL.Tx.Query
-  ( module Database.PostgreSQL.Tx.Query
+  ( PgQueryEnv
+  , PgQueryM
+  , Logger
+  , module Database.PostgreSQL.Tx.Query
   , module Database.PostgreSQL.Tx.Query.Internal.Reexport
   ) where
 
-import Control.Monad.Logger (LoggingT, runLoggingT)
-import Control.Monad.Trans (MonadTrans(lift))
+import Control.Exception (Exception)
 import Data.Int (Int64)
-import Database.PostgreSQL.Tx (Tx(TxEnv, tx), UnsafeTx(unsafeIOTx), TxM, unsafeRunTxM)
+import Database.PostgreSQL.Tx (TxM)
+import Database.PostgreSQL.Tx.Query.Internal
 import Database.PostgreSQL.Tx.Query.Internal.Reexport
+import GHC.Stack (HasCallStack)
 import qualified Database.PostgreSQL.Query as Query
-import qualified Database.PostgreSQL.Simple as Simple
 import qualified Database.PostgreSQL.Simple.Transaction as Simple
-import qualified Database.PostgreSQL.Tx.MonadLogger
-
-type PgQueryM = PgMonadT (LoggingT TxM)
-
-type Logger = Database.PostgreSQL.Tx.MonadLogger.Logger
+import qualified Database.PostgreSQL.Tx.Simple as Tx.Simple
 
-pgWithTransaction :: (Simple.Connection, Logger) -> TxM a -> IO a
+-- | Analogue of 'Query.pgWithTransaction'.
+--
+-- @since 0.1.0.0
+pgWithTransaction
+  :: (PgQueryEnv r, HasCallStack)
+  => r -> (HasCallStack => TxM r a) -> IO a
 pgWithTransaction = unsafeRunPgQueryTransaction Query.pgWithTransaction
 
-pgWithTransactionMode :: Simple.TransactionMode -> (Simple.Connection, Logger) -> TxM a -> IO a
+-- | Analogue of 'Query.pgWithTransactionMode'.
+--
+-- @since 0.1.0.0
+pgWithTransactionMode
+  :: (PgQueryEnv r, HasCallStack)
+  => Simple.TransactionMode -> r -> (HasCallStack => TxM r a) -> IO a
 pgWithTransactionMode m = unsafeRunPgQueryTransaction (Query.pgWithTransactionMode m)
 
--- Re-export of 'Query.pgQuery'
-pgQuery :: (ToSqlBuilder q, FromRow r) => q -> PgQueryM [r]
-pgQuery = unsafeIOTx . Query.pgQuery
+-- | Analogue of 'Query.pgWithTransactionSerializable'
+-- Unlike @postgresql-query@, uses 'shouldRetryTx' to also retry
+-- on @deadlock_detected@, not just @serialization_failure@.
+--
+-- Note that any 'IO' that occurs inside the 'TxM' may be executed multiple times.
+--
+-- @since 0.2.0.0
+pgWithTransactionSerializable
+  :: (PgQueryEnv r, HasCallStack)
+  => r -> (HasCallStack => TxM r a) -> IO a
+pgWithTransactionSerializable = Tx.Simple.withTransactionSerializable
 
--- Re-export of 'Query.pgExecute'
-pgExecute :: (ToSqlBuilder q) => q -> PgQueryM Int64
-pgExecute = unsafeIOTx . Query.pgExecute
+-- | Analogue of 'Query.pgWithTransactionModeRetry'.
+-- You should generally prefer 'pgWithTransactionSerializable'.
+--
+-- Note that any 'IO' that occurs inside the 'TxM' may be executed multiple times.
+--
+-- @since 0.2.0.0
+pgWithTransactionModeRetry
+  :: (PgQueryEnv r, Exception e, HasCallStack)
+  => Simple.TransactionMode -> (e -> Bool) -> r -> (HasCallStack => TxM r a) -> IO a
+pgWithTransactionModeRetry = Tx.Simple.withTransactionModeRetry
 
-unsafePgQueryIOTx :: PgMonadT (LoggingT IO) a -> PgQueryM a
-unsafePgQueryIOTx = unsafeIOTx
+-- | Analogue of 'Query.pgWithSavepoint'.
+--
+-- @since 0.2.0.0
+pgWithSavepoint :: (HasCallStack => PgQueryM a) -> PgQueryM a
+pgWithSavepoint x =
+  unsafeFromPgQueryIO
+    $ Query.pgWithSavepoint
+    $ unsafeToPgQueryIO x
 
-unsafeRunPgQueryTransaction
-  :: (PgMonadT (LoggingT IO) a -> PgMonadT (LoggingT IO) a)
-  -> (Simple.Connection, Logger)
-  -> TxM a
-  -> IO a
-unsafeRunPgQueryTransaction f (c, logger) x =
-  unsafeRunTxM
-    $ tx (c, logger)
-    $ unsafePgQueryIOTx
-    $ f
-    $ lift . lift
-    $ unsafeRunTxM x
+-- | Analogue of 'Query.pgQuery'.
+--
+-- @since 0.1.0.0
+pgQuery :: (ToSqlBuilder q, FromRow r, HasCallStack) => q -> PgQueryM [r]
+pgQuery = unsafeFromPgQueryIO . Query.pgQuery
 
-instance Tx PgQueryM where
-  type TxEnv PgQueryM = (Simple.Connection, Logger)
-  tx (conn, logger) x = runLoggingT (runPgMonadT conn x) logger
+-- | Analogue of 'Query.pgQueryWithMasker'.
+--
+-- @since 0.2.0.0
+pgQueryWithMasker :: (ToSqlBuilder q, FromRow r, HasCallStack) => LogMasker -> q -> PgQueryM [r]
+pgQueryWithMasker masker = unsafeFromPgQueryIO . Query.pgQueryWithMasker masker
 
-instance (UnsafeTx io t) => UnsafeTx (PgMonadT io) (PgMonadT t) where
-  unsafeIOTx (PgMonadT x) = PgMonadT $ unsafeIOTx x
+-- | Analogue of 'Query.pgExecute'.
+--
+-- @since 0.1.0.0
+pgExecute :: (ToSqlBuilder q, HasCallStack) => q -> PgQueryM Int64
+pgExecute = unsafeFromPgQueryIO . Query.pgExecute
+
+-- | Analogue of 'Query.pgExecuteWithMasker'.
+--
+-- @since 0.2.0.0
+pgExecuteWithMasker :: (ToSqlBuilder q, HasCallStack) => LogMasker -> q -> PgQueryM Int64
+pgExecuteWithMasker masker = unsafeFromPgQueryIO . Query.pgExecuteWithMasker masker
diff --git a/src/Database/PostgreSQL/Tx/Query/Internal.hs b/src/Database/PostgreSQL/Tx/Query/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Database/PostgreSQL/Tx/Query/Internal.hs
@@ -0,0 +1,97 @@
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE GeneralisedNewtypeDeriving #-}
+module Database.PostgreSQL.Tx.Query.Internal
+  ( -- * Disclaimer
+    -- $disclaimer
+
+    -- ** Internals
+    module Database.PostgreSQL.Tx.Query.Internal
+  ) where
+
+import Control.Monad.Base (MonadBase)
+import Control.Monad.Catch (MonadCatch, MonadMask, MonadThrow)
+import Control.Monad.IO.Class (MonadIO)
+import Control.Monad.Logger (MonadLogger(monadLoggerLog), MonadLoggerIO(askLoggerIO), toLogStr)
+import Control.Monad.Reader (ReaderT(ReaderT))
+import Control.Monad.Trans.Control (MonadBaseControl)
+import Data.Kind (Constraint)
+import Database.PostgreSQL.Tx (TxEnvs, TxM, askTxEnv, mapExceptionTx)
+import Database.PostgreSQL.Tx.Query.Internal.Reexport
+import Database.PostgreSQL.Tx.Unsafe (unsafeMkTxM, unsafeRunIOInTxM, unsafeRunTxM, unsafeUnTxM)
+import GHC.Stack (HasCallStack)
+import qualified Database.PostgreSQL.Simple as Simple
+import qualified Database.PostgreSQL.Tx.MonadLogger
+import qualified Database.PostgreSQL.Tx.Simple.Internal as Tx.Simple.Internal
+
+-- | Runtime environment needed to run @postgresql-query@ via @postgresql-tx@.
+--
+-- @since 0.2.0.0
+type PgQueryEnv r = (TxEnvs '[Simple.Connection, Logger] r) :: Constraint
+
+-- | Monad type alias for running @postgresql-query@ via @postgresql-tx@.
+--
+-- @since 0.2.0.0
+type PgQueryM a = forall r. (PgQueryEnv r) => TxM r a
+
+-- | Re-export of 'Database.PostgreSQL.Tx.MonadLogger.Logger'.
+--
+-- @since 0.1.0.0
+type Logger = Database.PostgreSQL.Tx.MonadLogger.Logger
+
+-- | Analogous to 'TxM' but allows for 'IO'. Useful so we can have
+-- instances which are required to run @postgresql-query@ functions.
+-- See 'unsafeToPgQueryIO' and 'unsafeFromPgQueryIO' for converting to/from
+-- 'TxM'.
+newtype UnsafePgQueryIO r a = UnsafePgQueryIO (ReaderT r IO a)
+  deriving newtype
+    ( Functor, Applicative, Monad, MonadIO
+    , MonadBase IO, MonadBaseControl IO, TransactionSafe
+    , MonadCatch, MonadMask, MonadThrow
+    )
+
+instance (PgQueryEnv r) => HasPostgres (UnsafePgQueryIO r) where
+  withPGConnection f = do
+    unsafeToPgQueryIO do
+      conn <- askTxEnv
+      unsafeFromPgQueryIO $ f conn
+
+instance (PgQueryEnv r) => MonadLogger (UnsafePgQueryIO r) where
+  monadLoggerLog loc src lvl msg = do
+    unsafeToPgQueryIO do
+      logger <- askTxEnv
+      unsafeRunIOInTxM $ logger loc src lvl (toLogStr msg)
+
+instance (PgQueryEnv r) => MonadLoggerIO (UnsafePgQueryIO r) where
+  askLoggerIO = unsafeToPgQueryIO askTxEnv
+
+unsafeToPgQueryIO :: (HasCallStack) => TxM r a -> UnsafePgQueryIO r a
+unsafeToPgQueryIO x = UnsafePgQueryIO $ unsafeUnTxM x
+
+unsafeFromPgQueryIO :: (HasCallStack) => UnsafePgQueryIO r a -> TxM r a
+unsafeFromPgQueryIO (UnsafePgQueryIO (ReaderT f)) =
+  mapExceptionTx (Just . Tx.Simple.Internal.fromSqlError) do
+    unsafeMkTxM f
+
+unsafeRunPgQueryTransaction
+  :: (PgQueryEnv r, HasCallStack)
+  => (HasCallStack => UnsafePgQueryIO r a -> UnsafePgQueryIO r a)
+  -> r
+  -> TxM r a
+  -> IO a
+unsafeRunPgQueryTransaction f r x =
+  unsafeRunTxM r
+    $ unsafeFromPgQueryIO
+    $ f
+    $ unsafeToPgQueryIO x
+
+-- $disclaimer
+--
+-- Changes to this module will not be reflected in the library's version
+-- updates.
diff --git a/src/Database/PostgreSQL/Tx/Query/Internal/Reexport.hs b/src/Database/PostgreSQL/Tx/Query/Internal/Reexport.hs
--- a/src/Database/PostgreSQL/Tx/Query/Internal/Reexport.hs
+++ b/src/Database/PostgreSQL/Tx/Query/Internal/Reexport.hs
@@ -10,8 +10,13 @@
   )
 -- Don't re-export names that we define in 'Database.PostgreSQL.Tx.Query'.
 import Database.PostgreSQL.Query as X hiding
-  ( pgWithTransaction
+  ( pgWithSavepoint
+  , pgWithTransaction
   , pgWithTransactionMode
+  , pgWithTransactionModeRetry
+  , pgWithTransactionSerializable
   , pgQuery
+  , pgQueryWithMasker
   , pgExecute
+  , pgExecuteWithMasker
   )
