git.iko.soy/typeable/postgresql-simple
on master help sign in
Fix spurious aborts when retrying transactions

Transactions that enter an error state must be aborted manually by issuing a "ROLLBACK". However, if the transaction error happened during a "COMMIT" then the rollback happens automatically. Issuing a "ROLLBACK" at this point causes PostgreSQL to issue a "WARNING: There is no transaction in progress". This warning can have much worse causes (e.g. you "COMMIT" but never began a transaction). This change makes the transaction retrying logic never cause PostgreSQL to issue this warning making it a more useful warning for detecting real bugs.

commit61837eb0834496d5320c51336a8f9e58343687e4 authorElliot Cameron <eacameron@gmail.com> dateFri 11 Oct 2019, 17:40 (7 years ago) parentfa9c19a
1 file changed+2−3
src/Database/PostgreSQL/Simple/Transaction.hs+2−3
src/Database/PostgreSQL/Simple/Transaction.hs+2−3
@@ -157,7 +157,7 @@ withTransactionModeRetry :: TransactionMode -> (SqlError -> Bool) -> Connection
157157withTransactionModeRetry mode shouldRetry conn act =
158158 mask $ \restore ->
159159 retryLoop $ E.try $ do
160− a <- restore act
160+ a <- restore act `E.onException` rollback_ conn
161161 commit conn
162162 return a
163163 where
@@ -166,8 +166,7 @@ withTransactionModeRetry mode shouldRetry conn act =
166166 beginMode mode conn
167167 r <- act'
168168 case r of
169− Left e -> do
170− rollback_ conn
169+ Left e ->
171170 case fmap shouldRetry (E.fromException e) of
172171 Just True -> retryLoop act'
173172 _ -> E.throwIO e