diff --git a/hasql-transaction.cabal b/hasql-transaction.cabal
--- a/hasql-transaction.cabal
+++ b/hasql-transaction.cabal
@@ -1,5 +1,5 @@
 name: hasql-transaction
-version: 0.10.0.1
+version: 0.10.0.2
 category: Hasql, Database, PostgreSQL
 synopsis: Composable abstraction over retryable transactions for Hasql
 homepage: https://github.com/nikita-volkov/hasql-transaction
diff --git a/library/Hasql/Transaction.hs b/library/Hasql/Transaction.hs
--- a/library/Hasql/Transaction.hs
+++ b/library/Hasql/Transaction.hs
@@ -56,7 +56,7 @@
 
 It cannot have an instance of Monad,
 because it makes it impossible to implement composition of
-mode and level associated with consituent transactions.
+mode and level associated with constituent transactions.
 It still however is possible to compose transactions
 in such a way that the result of a transaction is used
 to decide which transaction to execute next,
diff --git a/library/Hasql/Transaction/Sessions.hs b/library/Hasql/Transaction/Sessions.hs
--- a/library/Hasql/Transaction/Sessions.hs
+++ b/library/Hasql/Transaction/Sessions.hs
@@ -25,17 +25,23 @@
     in loop sessions
 
 tryTransaction :: Mode -> Level -> Session (a, Condemnation) -> Session (Maybe a)
-tryTransaction mode level session = do
+tryTransaction mode level body = do
+
   statement () (Statements.beginTransaction mode level)
-  catchError
-    (do
-      (result, condemnation) <- session
-      case condemnation of
-        Uncondemned -> statement () Statements.commitTransaction
-        Condemned -> statement () Statements.abortTransaction
-      return (Just result))
-    (\ error -> do
-      statement () Statements.abortTransaction
-      case error of
-        QueryError _ _ (ResultError (ServerError "40001" _ _ _)) -> return Nothing
-        error -> throwError error)
+
+  bodyRes <- catchError (fmap Just body) $ \ error -> do
+    statement () Statements.abortTransaction
+    handleTransactionError error $ return Nothing
+
+  case bodyRes of
+    Just (res, commit) -> catchError (commitOrAbort commit $> Just res) $ \ error -> do
+      handleTransactionError error $ return Nothing
+    Nothing -> return Nothing
+
+commitOrAbort = \ case
+  Uncondemned -> statement () Statements.commitTransaction
+  Condemned -> statement () Statements.abortTransaction
+
+handleTransactionError error onTransactionError = case error of
+  QueryError _ _ (ResultError (ServerError "40001" _ _ _)) -> onTransactionError
+  error -> throwError error
