diff --git a/hasql-transaction.cabal b/hasql-transaction.cabal
--- a/hasql-transaction.cabal
+++ b/hasql-transaction.cabal
@@ -1,7 +1,7 @@
 name: hasql-transaction
-version: 1
+version: 1.0.0.1
 category: Hasql, Database, PostgreSQL
-synopsis: A composable abstraction over the retryable transactions for Hasql
+synopsis: Composable abstraction over retryable transactions for Hasql
 homepage: https://github.com/nikita-volkov/hasql-transaction
 bug-reports: https://github.com/nikita-volkov/hasql-transaction/issues
 author: Nikita Volkov <nikita.y.volkov@mail.ru>
diff --git a/library/Hasql/Transaction/Private/Sessions.hs b/library/Hasql/Transaction/Private/Sessions.hs
--- a/library/Hasql/Transaction/Private/Sessions.hs
+++ b/library/Hasql/Transaction/Private/Sessions.hs
@@ -3,8 +3,8 @@
 
 import Hasql.Transaction.Private.Prelude
 import Hasql.Transaction.Private.Model
-import qualified Hasql.Session as A
-import qualified Hasql.Transaction.Private.Statements as B
+import Hasql.Session
+import qualified Hasql.Transaction.Private.Statements as Statements
 
 
 {-
@@ -12,23 +12,32 @@
 do one transaction retry in case of the 23505 error, and fail if an identical
 error is seen.
 -}
-inRetryingTransaction :: IsolationLevel -> Mode -> A.Session (a, Bool) -> A.Session a
-inRetryingTransaction isolation mode session =
-  fix $ \recur -> catchError normal (onError recur)
-  where
-    normal =
-      do
-        A.statement () (B.beginTransaction isolation mode)
-        (result, commit) <- session
-        if commit
-          then A.statement () B.commitTransaction
-          else A.statement () B.abortTransaction
-        return result
-    onError continue error =
-      do
-        A.statement () B.abortTransaction
-        case error of
-          A.QueryError _ _ (A.ResultError (A.ServerError "40001" _ _ _)) ->
-            continue
-          _ ->
-            throwError error
+inRetryingTransaction :: IsolationLevel -> Mode -> Session (a, Bool) -> Session a
+inRetryingTransaction level mode session =
+  fix $ \ retry -> do
+    attemptRes <- tryTransaction level mode session
+    case attemptRes of
+      Just a -> return a
+      Nothing -> retry
+
+tryTransaction :: IsolationLevel -> Mode -> Session (a, Bool) -> Session (Maybe a)
+tryTransaction level mode body = do
+
+  statement () (Statements.beginTransaction level mode)
+
+  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 commit = if commit
+  then statement () Statements.commitTransaction
+  else statement () Statements.abortTransaction
+
+handleTransactionError error onTransactionError = case error of
+  QueryError _ _ (ResultError (ServerError "40001" _ _ _)) -> onTransactionError
+  error -> throwError error
