Skip to content

Commit 7a2316c

Browse files
Azzerty23claude
andcommitted
fix(client): handle wrapped executor in sequential transactions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 86a2111 commit 7a2316c

1 file changed

Lines changed: 16 additions & 2 deletions

File tree

packages/orm/src/client/client-impl.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -626,8 +626,22 @@ function createModelCrudHandler(
626626
// Bind queryContext to the executor so onKyselyQuery hooks can read it.
627627
// Uses txClient's executor (which holds the tx connection) when in a transaction.
628628
const baseClient = txClient ?? client;
629-
const baseExecutor = (baseClient.$qb as any).getExecutor() as ZenStackQueryExecutor;
630-
const contextExecutor = baseExecutor.withQueryContext(queryContext);
629+
const rawExecutor = (baseClient.$qb as any).getExecutor();
630+
631+
let contextExecutor: ZenStackQueryExecutor;
632+
if (rawExecutor instanceof ZenStackQueryExecutor) {
633+
contextExecutor = rawExecutor.withQueryContext(queryContext);
634+
} else {
635+
// Kysely wraps the real executor in NotCommittedOrRolledBackAssertingExecutor
636+
// inside sequential transactions — delegate connection to rawExecutor so
637+
// queries run within the transaction.
638+
const rootZenExecutor = (client as unknown as ClientImpl).kyselyProps
639+
.executor as ZenStackQueryExecutor;
640+
contextExecutor = rootZenExecutor
641+
.withConnectionProvider({ provideConnection: (consumer) => rawExecutor.provideConnection(consumer) })
642+
.withQueryContext(queryContext);
643+
}
644+
631645
const contextClient = (baseClient as unknown as ClientImpl).withExecutor(
632646
contextExecutor,
633647
) as unknown as ClientContract<any>;

0 commit comments

Comments
 (0)