fix(09): WR-19 expose the write transaction to hooks and scopes through TxFromContext

This commit is contained in:
Jakub Zych
2026-10-01 21:37:13 +02:00
parent bbdc7a6b7e
commit 4ae272e3cc
6 changed files with 80 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
package cabana
import (
"context"
"gorm.io/gorm"
)
type txContextKey struct{}
// withTx returns ctx carrying the transaction a write is running in.
func withTx(ctx context.Context, tx *gorm.DB) context.Context {
if tx == nil {
return ctx
}
return context.WithValue(ctx, txContextKey{}, tx)
}
// TxFromContext returns the database transaction a write route is running in,
// for the context handed to a lifecycle hook (pact.FormBeforeCreate and the
// other Form and Relation hooks) or a scope (pact.FormExtendQuery) that runs
// inside it. A hook that has to read the database should use this handle
// instead of the application pool: it then sees the same snapshot as the write
// and does not take a second connection while the transaction holds row locks.
// The handle is valid only until the hook returns. The second result is false
// on routes that do not run in a transaction, such as the list.
func TxFromContext(ctx context.Context) (*gorm.DB, bool) {
if ctx == nil {
return nil, false
}
tx, ok := ctx.Value(txContextKey{}).(*gorm.DB)
return tx, ok && tx != nil
}