diff --git a/internal/db/read_writer.go b/internal/db/read_writer.go index adde78dc4..30b28d810 100644 --- a/internal/db/read_writer.go +++ b/internal/db/read_writer.go @@ -77,6 +77,9 @@ type Writer interface { // DoTx will wrap the TxHandler in a retryable transaction DoTx(ctx context.Context, retries uint, backOff Backoff, Handler TxHandler) (RetryInfo, error) + // IsTx returns true if there's an existing transaction in progress + IsTx(ctx context.Context) bool + // Update an object in the db, fieldMask is required and provides // field_mask.proto paths for fields that should be updated. The i interface // parameter is the type the caller wants to update in the db and its @@ -457,6 +460,11 @@ func (rw *Db) DoTx(ctx context.Context, retries uint, backOff Backoff, handler T } } +// IsTx returns true if there's an existing transaction in progress +func (rw *Db) IsTx(_ context.Context) bool { + return dbw.New(rw.underlying.wrapped.Load()).IsTx() +} + // LookupByPublicId will lookup resource by its public_id or private_id, which // must be unique. WithDebug is the only valid option, all other options are ignored. func (rw *Db) LookupById(ctx context.Context, resourceWithIder any, opt ...Option) error { diff --git a/internal/db/read_writer_ext_test.go b/internal/db/read_writer_ext_test.go index 5dae843b0..816be2ada 100644 --- a/internal/db/read_writer_ext_test.go +++ b/internal/db/read_writer_ext_test.go @@ -235,3 +235,21 @@ func TestDb_Create_OnConflict(t *testing.T) { assert.Equal(conflictUser.Name, foundUser.Name) }) } + +func TestRW_IsTx(t *testing.T) { + t.Parallel() + testCtx := context.Background() + conn, _ := db.TestSetup(t, "postgres") + rw := db.New(conn) + + assert, require := assert.New(t), require.New(t) + + assert.False(rw.IsTx(testCtx)) + + _, err := rw.DoTx(context.Background(), 10, db.ExpBackoff{}, + func(_ db.Reader, txWriter db.Writer) error { + assert.True(txWriter.IsTx(testCtx)) + return nil + }) + require.NoError(err) +}