Skip to content

Commit 6ad7d4d

Browse files
committed
update the running function to be clearer
1 parent 8d97d17 commit 6ad7d4d

File tree

2 files changed

+33
-17
lines changed

2 files changed

+33
-17
lines changed

cardano-db/src/Cardano/Db/Run.hs

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import Cardano.BM.Data.LogItem (
1212
mkLOMeta,
1313
)
1414
import Cardano.BM.Data.Severity (Severity (..))
15-
import Cardano.BM.Trace (Trace, logWarning)
15+
import Cardano.BM.Trace (Trace)
1616
import Cardano.Prelude
1717
import Control.Monad.IO.Unlift (withRunInIO)
1818
import Control.Monad.Logger (
@@ -94,8 +94,22 @@ sessionErrorToDbError cs sessionErr =
9494
-- Run DB actions with INTERRUPT HANDLING
9595
-----------------------------------------------------------------------------------------
9696

97-
-- | Run a DbAction with explicit transaction and isolation level
98-
-- This version properly handles interrupts (Ctrl+C) and ensures cleanup
97+
-- | Run a DbAction with explicit transaction control and isolation level
98+
--
99+
-- Transaction behavior:
100+
-- * Begins transaction with specified isolation level
101+
-- * Runs the action within the transaction
102+
-- * Commits if action succeeds, rollback only on commit failure or async exceptions
103+
-- * Returns Either for explicit error handling instead of throwing exceptions
104+
--
105+
-- Exception safety:
106+
-- * Uses 'mask' to prevent async exceptions during transaction lifecycle
107+
-- * Uses 'onException' to ensure rollback on interrupts (Ctrl+C, SIGTERM, etc.)
108+
-- * Does NOT rollback on action errors - lets them commit (matches Persistent semantics)
109+
--
110+
-- Note: This follows Persistent's philosophy where successful function calls commit
111+
-- their transactions regardless of the return value. Only async exceptions and
112+
-- commit failures trigger rollbacks.
99113
runDbActionWithIsolation ::
100114
MonadUnliftIO m =>
101115
DbEnv ->
@@ -104,28 +118,28 @@ runDbActionWithIsolation ::
104118
m (Either DbError a)
105119
runDbActionWithIsolation dbEnv isolationLevel action = do
106120
withRunInIO $ \runInIO -> do
121+
-- Use masking to prevent async exceptions during transaction management
107122
mask $ \restore -> do
108-
-- Begin transaction
123+
-- Begin transaction with specified isolation level
109124
beginResult <- beginTransaction dbEnv isolationLevel
110125
case beginResult of
111126
Left err -> pure (Left err)
112127
Right _ -> do
113-
-- Run the action with exception handling for interrupts
114-
result <-
115-
restore (runInIO $ runReaderT (runExceptT (runDbAction action)) dbEnv)
116-
`onException` do
117-
case dbTracer dbEnv of
118-
Just tracer -> logWarning tracer "rolling back transaction, due to interrupt."
119-
Nothing -> pure ()
120-
rollbackTransaction dbEnv
128+
-- Run action with async exception protection via onException
129+
-- If interrupted (Ctrl+C), the onException handler will rollback
130+
result <- onException
131+
(restore (runInIO $ runReaderT (runExceptT (runDbAction action)) dbEnv))
132+
(restore $ rollbackTransaction dbEnv)
121133
case result of
122-
Left err -> do
123-
rollbackTransaction dbEnv
124-
pure (Left err)
134+
-- Action returned error but ran successfully - commit the transaction
135+
-- This matches Persistent's behavior: successful calls always commit
136+
Left err -> pure (Left err)
125137
Right val -> do
138+
-- Attempt to commit the transaction
126139
commitResult <- commitTransaction dbEnv
127140
case commitResult of
128141
Left commitErr -> do
142+
-- Commit failed - rollback and return the commit error
129143
rollbackTransaction dbEnv
130144
pure (Left commitErr)
131145
Right _ -> pure (Right val)

cardano-db/src/Cardano/Db/Statement/OffChain.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import Cardano.Db.Schema.Types (PoolUrl, poolUrlDecoder, utcTimeAsTimestampDecod
2424
import Cardano.Db.Statement.Function.Core (ResultType (..), ResultTypeBulk (..), mkDbCallStack, runDbSession)
2525
import Cardano.Db.Statement.Function.Delete (parameterisedDeleteWhere)
2626
import Cardano.Db.Statement.Function.Insert (insertCheckUnique)
27-
import Cardano.Db.Statement.Function.InsertBulk (insertBulk)
27+
import Cardano.Db.Statement.Function.InsertBulk (ConflictStrategy (..), insertBulk, insertBulkWith)
2828
import Cardano.Db.Statement.Function.Query (countAll)
2929
import Cardano.Db.Statement.Pool (queryPoolHashIdExistsStmt, queryPoolMetadataRefIdExistsStmt)
3030
import Cardano.Db.Statement.Types (DbInfo (..))
@@ -550,7 +550,9 @@ insertBulkOffChainVoteExternalUpdatesStmt =
550550

551551
insertBulkOffChainVoteFetchErrorStmt :: HsqlStmt.Statement [SO.OffChainVoteFetchError] ()
552552
insertBulkOffChainVoteFetchErrorStmt =
553-
insertBulk
553+
insertBulkWith
554+
(IgnoreWithColumns ["voting_anchor_id", "retry_count"]) -- ON CONFLICT DO NOTHING
555+
False
554556
extractOffChainVoteFetchError
555557
SO.offChainVoteFetchErrorBulkEncoder
556558
NoResultBulk

0 commit comments

Comments
 (0)