fix(11-07): roll back the savepoint when a swallowed read failed

- beachcomber and lighthouse released their savepoint whenever the inner
  function reported no error; a Gate that counts a failed read as off,
  or a channel function or delete snapshot that swallows one, left the
  caller's Postgres transaction aborted (25P02) and failed the write
- a failed RELEASE now rolls back to the savepoint, as the READMEs promise
- beachcomber gets its testcontainers harness and sync tests
  (TestSyncGates, TestSyncAfterCommit, TestSyncDeleteAndSoftDelete,
  TestSyncFailuresNonFatal, TestServiceSetup); lighthouse gets
  TestBroadcastSwallowedReadFailure
This commit is contained in:
Jakub Zych
2026-09-30 14:26:51 +02:00
parent 6dadbf6957
commit 6df43d45b8
7 changed files with 890 additions and 4 deletions

View File

@@ -469,7 +469,12 @@ func (s *Service) inSavepoint(db *gorm.DB, fn func(tx *gorm.DB) error) {
}
return
}
if inTx {
if inTx && tx.Exec("RELEASE SAVEPOINT "+savepoint).Error != nil {
// A statement inside fn failed although fn did not report it (a
// channel or payload function that treats a failed read as "no
// broadcast", or the delete snapshot's reload): the transaction is
// aborted and only a rollback to the savepoint keeps the write alive.
tx.RollbackTo(savepoint)
tx.Exec("RELEASE SAVEPOINT " + savepoint)
}
}