sqlstack 3.5.0 → 3.6.0-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/codegen/generateManifest.d.ts +3 -1
- package/dist/cjs/codegen/generateManifest.d.ts.map +1 -1
- package/dist/cjs/codegen/generateManifest.js +195 -3
- package/dist/cjs/codegen/generateManifest.js.map +1 -1
- package/dist/cjs/core/fileResolution.d.ts +7 -0
- package/dist/cjs/core/fileResolution.d.ts.map +1 -1
- package/dist/cjs/core/fileResolution.js +53 -14
- package/dist/cjs/core/fileResolution.js.map +1 -1
- package/dist/cjs/core/metadata.d.ts +5 -0
- package/dist/cjs/core/metadata.d.ts.map +1 -1
- package/dist/cjs/core/metadata.js.map +1 -1
- package/dist/cjs/core/resources.d.ts +36 -0
- package/dist/cjs/core/resources.d.ts.map +1 -0
- package/dist/cjs/core/resources.js +98 -0
- package/dist/cjs/core/resources.js.map +1 -0
- package/dist/cjs/core/sourceScanResolver.d.ts +8 -14
- package/dist/cjs/core/sourceScanResolver.d.ts.map +1 -1
- package/dist/cjs/core/sourceScanResolver.js +8 -20
- package/dist/cjs/core/sourceScanResolver.js.map +1 -1
- package/dist/cjs/decorators/query.d.ts.map +1 -1
- package/dist/cjs/decorators/query.js +96 -35
- package/dist/cjs/decorators/query.js.map +1 -1
- package/dist/cjs/family.d.ts.map +1 -1
- package/dist/cjs/family.js +3 -1
- package/dist/cjs/family.js.map +1 -1
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +4 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/run.d.ts +44 -4
- package/dist/cjs/run.d.ts.map +1 -1
- package/dist/cjs/run.js +38 -7
- package/dist/cjs/run.js.map +1 -1
- package/dist/cjs/runtime.d.ts +6 -0
- package/dist/cjs/runtime.d.ts.map +1 -1
- package/dist/cjs/runtime.js +18 -0
- package/dist/cjs/runtime.js.map +1 -1
- package/dist/cjs/stack.d.ts +14 -0
- package/dist/cjs/stack.d.ts.map +1 -1
- package/dist/cjs/stack.js +20 -0
- package/dist/cjs/stack.js.map +1 -1
- package/dist/cjs/transactions.d.ts +52 -0
- package/dist/cjs/transactions.d.ts.map +1 -1
- package/dist/cjs/transactions.js +557 -3
- package/dist/cjs/transactions.js.map +1 -1
- package/dist/esm/codegen/generateManifest.js +195 -3
- package/dist/esm/codegen/generateManifest.js.map +1 -1
- package/dist/esm/core/fileResolution.js +52 -14
- package/dist/esm/core/fileResolution.js.map +1 -1
- package/dist/esm/core/metadata.js.map +1 -1
- package/dist/esm/core/resources.js +91 -0
- package/dist/esm/core/resources.js.map +1 -0
- package/dist/esm/core/sourceScanResolver.js +8 -19
- package/dist/esm/core/sourceScanResolver.js.map +1 -1
- package/dist/esm/decorators/query.js +101 -40
- package/dist/esm/decorators/query.js.map +1 -1
- package/dist/esm/family.js +3 -1
- package/dist/esm/family.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/run.js +38 -8
- package/dist/esm/run.js.map +1 -1
- package/dist/esm/runtime.js +17 -0
- package/dist/esm/runtime.js.map +1 -1
- package/dist/esm/stack.js +21 -1
- package/dist/esm/stack.js.map +1 -1
- package/dist/esm/transactions.js +554 -3
- package/dist/esm/transactions.js.map +1 -1
- package/package.json +1 -1
- package/readme.md +74 -133
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transactions.js","sourceRoot":"","sources":["../../src/transactions.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\nimport type { Database, QueryResult } from './registry';\nimport { createPgDb, createMysqlDb } from './adapters';\nimport { RollbackTransactionError, SqlStackError } from './core/errors';\nimport type { DatabaseEntry } from './stack';\nimport { resolveExecution, legacyEntry } from './runtime';\n\nexport type TransactionOptions = {\n db?: string;\n lazy?: boolean;\n nested?: 'join';\n};\n\n// Keyed by concrete DatabaseEntry identity (owning stack + registration), so\n// two roots transacting on the same name (\"primary\") can never collide\n// (spec 16 §20, spec 17 §14).\ntype TxStore = {\n txByDb: Map<DatabaseEntry, TxState>;\n};\n\nconst als = new AsyncLocalStorage<TxStore>();\n\nfunction getStore(): TxStore | undefined {\n return als.getStore();\n}\n\nfunction getOrCreateStore(): { store: TxStore; isNew: boolean } {\n const existing = getStore();\n if (existing) return { store: existing, isNew: false };\n return { store: { txByDb: new Map() }, isNew: true };\n}\n\nfunction isRollbackTransactionError(err: unknown): err is RollbackTransactionError {\n return err instanceof RollbackTransactionError;\n}\n\nfunction unwrapRollbackCause(err: RollbackTransactionError): unknown {\n return typeof err.cause === 'undefined' ? err : err.cause;\n}\n\nexport class TransactionHandle {\n readonly entry: DatabaseEntry;\n #state: TxState;\n #owned: boolean;\n #finished = false;\n\n constructor(entry: DatabaseEntry, state: TxState, owned: boolean) {\n this.entry = entry;\n this.#state = state;\n this.#owned = owned;\n }\n\n get dbName(): string {\n return this.entry.name;\n }\n\n async ensureStarted() {\n await this.#state.ensureStarted();\n }\n\n rollbackOnly(errorToThrow?: unknown) {\n this.#state.rollbackOnly = true;\n if (typeof errorToThrow !== 'undefined') {\n this.#state.rollbackError = errorToThrow;\n }\n }\n\n async commit() {\n if (!this.#owned) return;\n await this.#state.commitIfStarted();\n }\n\n async rollback() {\n if (!this.#owned) return;\n await this.#state.rollbackIfStarted();\n }\n\n async release() {\n if (!this.#owned) return;\n await this.#state.release();\n }\n\n async finishOnSuccess() {\n if (!this.#owned || this.#finished) return;\n this.#finished = true;\n await this.#state.finishOnSuccess();\n }\n\n async finishOnError(err: unknown) {\n if (!this.#owned || this.#finished) return;\n this.#finished = true;\n await this.#state.finishOnError(err);\n }\n}\n\nclass TxState {\n readonly entry: DatabaseEntry;\n readonly db: Database;\n readonly options: Required<Pick<TransactionOptions, 'lazy'>> & Pick<TransactionOptions, 'nested'>;\n depth = 1;\n started = false;\n completed = false;\n rollbackOnly = false;\n rollbackError: unknown | undefined;\n\n private txDb: Database | undefined;\n private releaseFn: (() => Promise<void>) | undefined;\n\n constructor(entry: DatabaseEntry, options: TransactionOptions | undefined) {\n this.entry = entry;\n this.db = entry.db;\n this.options = {\n lazy: options?.lazy ?? true,\n nested: options?.nested ?? 'join',\n };\n }\n\n get activeDb(): Database {\n return this.txDb ?? this.db;\n }\n\n async ensureStarted() {\n if (this.started) return;\n\n const dialect = this.db.dialect ?? 'sqlite';\n if (dialect === 'postgres') {\n const pool: any = this.db.conn;\n if (!pool || typeof pool.connect !== 'function') {\n throw new SqlStackError('Postgres transactions require a pg Pool with .connect() as Database.conn');\n }\n const client = await pool.connect();\n this.txDb = createPgDb(client);\n this.releaseFn = async () => {\n if (typeof client.release === 'function') client.release();\n };\n await this.txDb.query('BEGIN', []);\n this.started = true;\n return;\n }\n\n if (dialect === 'mysql') {\n const pool: any = this.db.conn;\n if (!pool || typeof pool.getConnection !== 'function') {\n throw new SqlStackError('MySQL transactions require a mysql2 Pool with .getConnection() as Database.conn');\n }\n const conn = await pool.getConnection();\n this.txDb = createMysqlDb(conn);\n this.releaseFn = async () => {\n if (typeof conn.release === 'function') conn.release();\n };\n await this.txDb.query('START TRANSACTION', []);\n this.started = true;\n return;\n }\n\n // sqlite: existing connection is already bound\n await this.db.query('BEGIN', []);\n this.started = true;\n }\n\n async query(sql: string, params: unknown[]): Promise<QueryResult> {\n await this.ensureStarted();\n return await this.activeDb.query(sql, params);\n }\n\n async commitIfStarted() {\n if (this.completed) return;\n if (!this.started) {\n this.completed = true;\n return;\n }\n await this.activeDb.query('COMMIT', []);\n this.completed = true;\n }\n\n async rollbackIfStarted() {\n if (this.completed) return;\n if (!this.started) {\n this.completed = true;\n return;\n }\n await this.activeDb.query('ROLLBACK', []);\n this.completed = true;\n }\n\n async release() {\n try {\n if (this.releaseFn) await this.releaseFn();\n } finally {\n this.txDb = undefined;\n this.releaseFn = undefined;\n }\n }\n\n async finishOnSuccess() {\n try {\n if (this.rollbackOnly) {\n await this.rollbackIfStarted();\n if (typeof this.rollbackError !== 'undefined') throw this.rollbackError;\n throw new RollbackTransactionError();\n }\n await this.commitIfStarted();\n } finally {\n await this.release();\n }\n }\n\n async finishOnError(err: unknown) {\n try {\n await this.rollbackIfStarted();\n } finally {\n await this.release();\n }\n if (isRollbackTransactionError(err)) {\n throw unwrapRollbackCause(err);\n }\n throw err;\n }\n}\n\nfunction enterTx(entry: DatabaseEntry, options?: TransactionOptions): { handle: TransactionHandle; store: TxStore; isNewStore: boolean } {\n const { store, isNew } = getOrCreateStore();\n const existing = store.txByDb.get(entry);\n if (existing) {\n existing.depth++;\n return { handle: new TransactionHandle(entry, existing, false), store, isNewStore: isNew };\n }\n const state = new TxState(entry, options);\n store.txByDb.set(entry, state);\n return { handle: new TransactionHandle(entry, state, true), store, isNewStore: isNew };\n}\n\nasync function exitTx(entry: DatabaseEntry, store: TxStore) {\n const state = store.txByDb.get(entry);\n if (!state) return;\n state.depth = Math.max(0, state.depth - 1);\n if (state.depth === 0) {\n store.txByDb.delete(entry);\n }\n}\n\n/**\n * @deprecated Synchronous lookup against the legacy global registry only.\n * Under an active IoC root, use `currentTransactionFor(entry)` with an entry\n * from the root's SqlStack (`stack.getEntry(name)`).\n */\nexport function currentTransaction(db?: string): TransactionHandle | undefined {\n const store = getStore();\n if (!store) return undefined;\n const entry = legacyEntry(db);\n const state = store.txByDb.get(entry);\n if (!state) return undefined;\n return new TransactionHandle(entry, state, false);\n}\n\n/**\n * Whether this async call carries any transaction records. This observation\n * never resolves a database, opens a connection, or consults legacy defaults.\n * It does not choose an owner: use currentTransactionFor(entry) for that.\n */\nexport function hasTransactionContext(): boolean {\n return (getStore()?.txByDb.size ?? 0) > 0;\n}\n\n/** Active transaction handle for a concrete database entry, if any. */\nexport function currentTransactionFor(entry: DatabaseEntry): TransactionHandle | undefined {\n const store = getStore();\n const state = store?.txByDb.get(entry);\n if (!state) return undefined;\n return new TransactionHandle(entry, state, false);\n}\n\nexport async function withTransaction<T>(fn: () => Promise<T>, options?: TransactionOptions): Promise<T> {\n const { entry } = await resolveExecution(options?.db);\n const { handle, store, isNewStore } = enterTx(entry, options);\n\n const run = async () => {\n try {\n const out = await fn();\n await handle.finishOnSuccess();\n return out;\n } catch (err) {\n await handle.finishOnError(err);\n throw err;\n } finally {\n await exitTx(entry, store);\n }\n };\n\n return isNewStore ? await als.run(store, run) : await run();\n}\n\nexport type TransactionDecorator = {\n (target: any, prop: string | symbol, desc: PropertyDescriptor): void;\n (options?: TransactionOptions): (target: any, prop: string | symbol, desc: PropertyDescriptor) => void;\n};\n\nexport const transaction: TransactionDecorator = function (...args: any[]) {\n // @transaction\n if (args.length === 3 && typeof args[2]?.value === 'function') {\n const [target, prop, desc] = args as [any, string | symbol, PropertyDescriptor];\n wrapMethod(target, prop, desc, undefined);\n return;\n }\n // @transaction() or @transaction({ ... })\n const options: TransactionOptions | undefined = args.length > 0 ? args[0] : undefined;\n return function (target: any, prop: string | symbol, desc: PropertyDescriptor) {\n wrapMethod(target, prop, desc, options);\n };\n} as any;\n\nfunction wrapMethod(_target: any, _prop: string | symbol, desc: PropertyDescriptor, options?: TransactionOptions) {\n const original = desc.value;\n desc.value = async function (...callArgs: any[]) {\n return await withTransaction(() => original.apply(this, callArgs), options);\n };\n}\n\nexport type ActiveTransaction = {\n query(sql: string, params: unknown[]): Promise<QueryResult>;\n};\n\nexport function getActiveTransaction(entry: DatabaseEntry): ActiveTransaction | undefined {\n const store = getStore();\n return store?.txByDb.get(entry);\n}\n\n/**\n * Active transaction whose registered database is exactly `db` (object\n * identity), if any. `run(db, ...)` uses this so a handle passed at call time\n * joins a transaction opened on the same database (by `@transaction` or\n * `withTransaction`) instead of bypassing it. A handle that was never\n * registered with a SqlStack (or the legacy registry) never matches.\n */\nexport function getActiveTransactionForDatabase(db: object): ActiveTransaction | undefined {\n const store = getStore();\n if (!store) return undefined;\n for (const state of store.txByDb.values()) {\n if (state.db === db) return state;\n }\n return undefined;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"transactions.js","sourceRoot":"","sources":["../../src/transactions.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\nimport type { Database, QueryResult } from './registry';\nimport { createPgDb, createMysqlDb } from './adapters';\nimport { RollbackTransactionError, SqlStackError } from './core/errors';\nimport type { DatabaseEntry } from './stack';\nimport { resolveExecution, legacyEntry } from './runtime';\n\nexport type TransactionOptions = {\n db?: string;\n lazy?: boolean;\n nested?: 'join';\n};\n\n/** Work registered with transaction.afterCommit / transaction.afterSettled. */\nexport type TransactionHook = () => unknown;\n\n/** Observable transaction events (see onTransactionEvent). */\nexport type TransactionEvent = {\n readonly type: 'sqlstack.transaction.multi_database';\n /** Names of the databases the scope has opened, in open order. */\n readonly databases: readonly string[];\n};\n\nexport type TransactionEventListener = (event: TransactionEvent) => void;\n\n// Keyed by concrete DatabaseEntry identity (owning stack + registration), so\n// two roots transacting on the same name (\"primary\") can never collide\n// (spec 16 §20, spec 17 §14). `scope` is the innermost @transaction scope of\n// this flow; the map is shared by every scope of one flow.\ntype TxStore = {\n txByDb: Map<DatabaseEntry, TxState>;\n scope?: TxScope;\n};\n\nconst als = new AsyncLocalStorage<TxStore>();\n\nfunction getStore(): TxStore | undefined {\n return als.getStore();\n}\n\nfunction getOrCreateStore(): { store: TxStore; isNew: boolean } {\n const existing = getStore();\n if (existing) return { store: existing, isNew: false };\n return { store: { txByDb: new Map() }, isNew: true };\n}\n\nfunction isRollbackTransactionError(err: unknown): err is RollbackTransactionError {\n return err instanceof RollbackTransactionError;\n}\n\nfunction unwrapRollbackCause(err: RollbackTransactionError): unknown {\n return typeof err.cause === 'undefined' ? err : err.cause;\n}\n\nexport class TransactionHandle {\n readonly entry: DatabaseEntry;\n #state: TxState;\n #owned: boolean;\n #finished = false;\n\n constructor(entry: DatabaseEntry, state: TxState, owned: boolean) {\n this.entry = entry;\n this.#state = state;\n this.#owned = owned;\n }\n\n get dbName(): string {\n return this.entry.name;\n }\n\n async ensureStarted() {\n await this.#state.ensureStarted();\n }\n\n rollbackOnly(errorToThrow?: unknown) {\n this.#state.rollbackOnly = true;\n if (typeof errorToThrow !== 'undefined') {\n this.#state.rollbackError = errorToThrow;\n }\n }\n\n async commit() {\n if (!this.#owned) return;\n await this.#state.commitIfStarted();\n }\n\n async rollback() {\n if (!this.#owned) return;\n await this.#state.rollbackIfStarted();\n }\n\n async release() {\n if (!this.#owned) return;\n await this.#state.release();\n }\n\n async finishOnSuccess() {\n if (!this.#owned || this.#finished) return;\n this.#finished = true;\n await this.#state.finishOnSuccess();\n }\n\n async finishOnError(err: unknown) {\n if (!this.#owned || this.#finished) return;\n this.#finished = true;\n await this.#state.finishOnError(err);\n }\n}\n\nclass TxState {\n readonly entry: DatabaseEntry;\n readonly db: Database;\n readonly options: Required<Pick<TransactionOptions, 'lazy'>> & Pick<TransactionOptions, 'nested'>;\n depth = 1;\n started = false;\n completed = false;\n rollbackOnly = false;\n rollbackError: unknown | undefined;\n /** SQLite opening statement: name-based transactions keep plain BEGIN. */\n sqliteBegin: 'BEGIN' | 'BEGIN IMMEDIATE' = 'BEGIN';\n /** Called once when the transaction releases its connection (SQLite queue turn). */\n onRelease: (() => void) | undefined;\n\n private txDb: Database | undefined;\n private releaseFn: (() => Promise<void>) | undefined;\n\n constructor(entry: DatabaseEntry, options: TransactionOptions | undefined) {\n this.entry = entry;\n this.db = entry.db;\n this.options = {\n lazy: options?.lazy ?? true,\n nested: options?.nested ?? 'join',\n };\n }\n\n get activeDb(): Database {\n return this.txDb ?? this.db;\n }\n\n async ensureStarted() {\n if (this.started) return;\n\n const dialect = this.db.dialect ?? 'sqlite';\n if (dialect === 'postgres') {\n const pool: any = this.db.conn;\n if (!pool || typeof pool.connect !== 'function') {\n throw new SqlStackError('Postgres transactions require a pg Pool with .connect() as Database.conn');\n }\n const client = await pool.connect();\n this.txDb = createPgDb(client);\n this.releaseFn = async () => {\n if (typeof client.release === 'function') client.release();\n };\n await this.txDb.query('BEGIN', []);\n this.started = true;\n return;\n }\n\n if (dialect === 'mysql') {\n const pool: any = this.db.conn;\n if (!pool || typeof pool.getConnection !== 'function') {\n throw new SqlStackError('MySQL transactions require a mysql2 Pool with .getConnection() as Database.conn');\n }\n const conn = await pool.getConnection();\n this.txDb = createMysqlDb(conn);\n this.releaseFn = async () => {\n if (typeof conn.release === 'function') conn.release();\n };\n await this.txDb.query('START TRANSACTION', []);\n this.started = true;\n return;\n }\n\n // sqlite: existing connection is already bound\n await this.db.query(this.sqliteBegin, []);\n this.started = true;\n }\n\n async query(sql: string, params: unknown[]): Promise<QueryResult> {\n await this.ensureStarted();\n return await this.activeDb.query(sql, params);\n }\n\n async commitIfStarted() {\n if (this.completed) return;\n if (!this.started) {\n this.completed = true;\n return;\n }\n await this.activeDb.query('COMMIT', []);\n this.completed = true;\n }\n\n async rollbackIfStarted() {\n if (this.completed) return;\n if (!this.started) {\n this.completed = true;\n return;\n }\n await this.activeDb.query('ROLLBACK', []);\n this.completed = true;\n }\n\n async release() {\n try {\n if (this.releaseFn) await this.releaseFn();\n } finally {\n this.txDb = undefined;\n this.releaseFn = undefined;\n const onRelease = this.onRelease;\n this.onRelease = undefined;\n onRelease?.();\n }\n }\n\n async finishOnSuccess() {\n try {\n if (this.rollbackOnly) {\n await this.rollbackIfStarted();\n if (typeof this.rollbackError !== 'undefined') throw this.rollbackError;\n throw new RollbackTransactionError();\n }\n await this.commitIfStarted();\n } finally {\n await this.release();\n }\n }\n\n async finishOnError(err: unknown) {\n try {\n await this.rollbackIfStarted();\n } finally {\n await this.release();\n }\n if (isRollbackTransactionError(err)) {\n throw unwrapRollbackCause(err);\n }\n throw err;\n }\n}\n\nfunction enterTx(entry: DatabaseEntry, options?: TransactionOptions): { handle: TransactionHandle; store: TxStore; isNewStore: boolean } {\n const { store, isNew } = getOrCreateStore();\n const existing = store.txByDb.get(entry);\n if (existing) {\n existing.depth++;\n return { handle: new TransactionHandle(entry, existing, false), store, isNewStore: isNew };\n }\n const state = new TxState(entry, options);\n store.txByDb.set(entry, state);\n return { handle: new TransactionHandle(entry, state, true), store, isNewStore: isNew };\n}\n\nasync function exitTx(entry: DatabaseEntry, store: TxStore) {\n const state = store.txByDb.get(entry);\n if (!state) return;\n state.depth = Math.max(0, state.depth - 1);\n if (state.depth === 0) {\n store.txByDb.delete(entry);\n }\n}\n\n/**\n * @deprecated Synchronous lookup against the legacy global registry only.\n * Under an active IoC root, use `currentTransactionFor(entry)` with an entry\n * from the root's SqlStack (`stack.getEntry(name)`).\n */\nexport function currentTransaction(db?: string): TransactionHandle | undefined {\n const store = getStore();\n if (!store) return undefined;\n const entry = legacyEntry(db);\n const state = store.txByDb.get(entry);\n if (!state) return undefined;\n return new TransactionHandle(entry, state, false);\n}\n\n/**\n * Whether this async call carries any transaction records. This observation\n * never resolves a database, opens a connection, or consults legacy defaults.\n * It does not choose an owner: use currentTransactionFor(entry) for that.\n */\nexport function hasTransactionContext(): boolean {\n return (getStore()?.txByDb.size ?? 0) > 0;\n}\n\n/** Active transaction handle for a concrete database entry, if any. */\nexport function currentTransactionFor(entry: DatabaseEntry): TransactionHandle | undefined {\n const store = getStore();\n const state = store?.txByDb.get(entry);\n if (!state) return undefined;\n return new TransactionHandle(entry, state, false);\n}\n\nexport async function withTransaction<T>(fn: () => Promise<T>, options?: TransactionOptions): Promise<T> {\n const { entry } = await resolveExecution(options?.db);\n const { handle, store, isNewStore } = enterTx(entry, options);\n\n const run = async () => {\n try {\n const out = await fn();\n await handle.finishOnSuccess();\n return out;\n } catch (err) {\n await handle.finishOnError(err);\n throw err;\n } finally {\n await exitTx(entry, store);\n }\n };\n\n return isNewStore ? await als.run(store, run) : await run();\n}\n\n// ---------------------------------------------------------------------------\n// Scope-based @transaction (docs/transactions.md)\n// ---------------------------------------------------------------------------\n\n/**\n * One @transaction method invocation. The root scope (no parent) owns every\n * transaction opened in the flow and commits/rolls them back at its exit; a\n * nested scope is a piece of its parent, delimited by savepoints.\n */\nclass TxScope {\n readonly parent: TxScope | undefined;\n readonly root: TxScope;\n readonly depth: number;\n closed = false;\n markAll = false;\n readonly marked = new Set<TxState>();\n afterCommit: TransactionHook[] = [];\n afterSettled: TransactionHook[] = [];\n /** Nested scopes: the savepoint this scope holds on each open transaction. */\n readonly savepoints: Array<{ state: TxState; name: string }> = [];\n\n // Root-only bookkeeping.\n /** Transactions opened in this flow, in open order (root commits them). */\n readonly opened: TxState[] = [];\n readonly opening = new Map<DatabaseEntry, Promise<TxState>>();\n /** Databases this root has opened (multi_database event), with their reported names. */\n readonly seen: Array<{ entry: DatabaseEntry; name: string }> = [];\n savepointSeq = 0;\n\n /** Siblings share one savepoint stack; descendants queue on their own parent. */\n private childTail: Promise<void> = Promise.resolve();\n\n constructor(parent: TxScope | undefined) {\n this.parent = parent;\n this.root = parent ? parent.root : this;\n this.depth = parent ? parent.depth + 1 : 1;\n }\n\n get hasMarks(): boolean {\n return this.markAll || this.marked.size > 0;\n }\n\n isMarked(state: TxState): boolean {\n return this.markAll || this.marked.has(state);\n }\n\n reserveChild(): { ready: Promise<void>; release: () => void } {\n const ready = this.childTail;\n let release!: () => void;\n this.childTail = new Promise<void>((resolve) => {\n release = resolve;\n });\n return { ready, release };\n }\n\n async waitForChildren(): Promise<void> {\n let observed: Promise<void>;\n do {\n observed = this.childTail;\n await observed;\n } while (observed !== this.childTail);\n }\n}\n\nconst eventListeners = new Set<TransactionEventListener>();\n\n/**\n * Observe transaction trace events. Today the only event is\n * `sqlstack.transaction.multi_database`, emitted once per root scope the\n * moment it opens its second database. Returns an unsubscribe function.\n * Listener errors are ignored so observation never affects a transaction.\n */\nexport function onTransactionEvent(listener: TransactionEventListener): () => void {\n eventListeners.add(listener);\n return () => {\n eventListeners.delete(listener);\n };\n}\n\nfunction emitTransactionEvent(event: TransactionEvent): void {\n for (const listener of [...eventListeners]) {\n try {\n listener(event);\n } catch {\n // observation must never affect the transaction\n }\n }\n}\n\n/** Innermost scope of this flow that has not exited yet. */\nfunction activeScope(store: TxStore | undefined): TxScope | undefined {\n let scope = store?.scope;\n while (scope && scope.closed) scope = scope.parent;\n return scope;\n}\n\nfunction requireScope(api: string): TxScope {\n const scope = activeScope(getStore());\n if (!scope) {\n throw new SqlStackError(`transaction.${api}() called outside a @transaction method.`);\n }\n return scope;\n}\n\n// SQLite serialisation: one connection carries one transaction at a time, so\n// independent flows opening a scope transaction on the same connection wait\n// for the previous holder to release instead of failing with \"cannot start a\n// transaction within a transaction\". Keyed by the Database object (the\n// connection), which is the entry's database.\nconst sqliteTails = new WeakMap<object, Promise<void>>();\n\nasync function acquireSqliteTurn(db: object): Promise<() => void> {\n const previous = sqliteTails.get(db) ?? Promise.resolve();\n let release!: () => void;\n const mine = new Promise<void>((resolve) => {\n release = resolve;\n });\n sqliteTails.set(\n db,\n previous.then(() => mine)\n );\n await previous;\n let released = false;\n return () => {\n if (released) return;\n released = true;\n release();\n };\n}\n\nasync function issueSavepoint(scope: TxScope, state: TxState): Promise<void> {\n const name = `sqlstack_sp_${scope.depth}_${++scope.root.savepointSeq}`;\n await state.query(`SAVEPOINT ${name}`, []);\n scope.savepoints.push({ state, name });\n}\n\n// A Database handle given to run(db, ...) that a @transaction scope opens a\n// transaction on gets one synthetic entry per handle object, so the scope's\n// TxState is keyed by the handle itself. Never registered anywhere; the name is\n// a label only (excluded from name matching in transaction.rollback(name)).\nconst HANDLE_LABEL = 'handle';\nconst handleEntries = new WeakMap<object, DatabaseEntry>();\nconst syntheticEntries = new WeakSet<DatabaseEntry>();\n\nfunction handleEntryFor(db: object): DatabaseEntry {\n let entry = handleEntries.get(db);\n if (!entry) {\n entry = { name: HANDLE_LABEL, db: db as Database, owned: false, stack: undefined } as unknown as DatabaseEntry;\n handleEntries.set(db, entry);\n syntheticEntries.add(entry);\n }\n return entry;\n}\n\nfunction isHandleEntry(entry: DatabaseEntry): boolean {\n return syntheticEntries.has(entry);\n}\n\n/**\n * Whether a transaction keyed by `other` is the transaction `entry` must join:\n * the same entry, or — when either side was opened through a handle — the\n * same database object (identity). Two registered entries that merely share\n * a Database are left as they were.\n */\nfunction sameTransactionTarget(entry: DatabaseEntry, other: DatabaseEntry): boolean {\n if (entry === other) return true;\n return (isHandleEntry(entry) || isHandleEntry(other)) && entry.db === other.db;\n}\n\nfunction findOpenTransaction(store: TxStore, entry: DatabaseEntry): TxState | undefined {\n const direct = store.txByDb.get(entry);\n if (direct) return direct;\n for (const [key, state] of store.txByDb) {\n if (!state.completed && sameTransactionTarget(entry, key)) return state;\n }\n return undefined;\n}\n\nfunction findPendingOpen(root: TxScope, entry: DatabaseEntry): Promise<TxState> | undefined {\n const direct = root.opening.get(entry);\n if (direct) return direct;\n for (const [key, pending] of root.opening) {\n if (sameTransactionTarget(entry, key)) return pending;\n }\n return undefined;\n}\n\n/** Name reported for `entry` in the multi_database event. */\nfunction reportedName(store: TxStore, entry: DatabaseEntry): string {\n if (!isHandleEntry(entry)) return entry.name;\n // A handle that is the database of a registered entry this flow knows uses that name.\n for (const key of store.txByDb.keys()) {\n if (!isHandleEntry(key) && key.db === entry.db) return key.name;\n }\n return HANDLE_LABEL;\n}\n\nasync function openScopedTransaction(store: TxStore, scope: TxScope, entry: DatabaseEntry): Promise<TxState> {\n const existing = findOpenTransaction(store, entry);\n if (existing) return existing;\n const root = scope.root;\n const pending = findPendingOpen(root, entry);\n if (pending) return await pending;\n\n const open = (async () => {\n const state = new TxState(entry, undefined);\n state.sqliteBegin = 'BEGIN IMMEDIATE';\n const dialect = entry.db.dialect ?? 'sqlite';\n // A flow that already holds this connection must not wait on itself.\n const holdsConnection = root.opened.some((s) => s.db === entry.db && !s.completed);\n if (dialect === 'sqlite' && !holdsConnection) {\n state.onRelease = await acquireSqliteTurn(entry.db);\n }\n try {\n await state.ensureStarted();\n } catch (err) {\n await state.release();\n throw err;\n }\n store.txByDb.set(entry, state);\n root.opened.push(state);\n\n if (!root.seen.some((s) => sameTransactionTarget(entry, s.entry))) {\n root.seen.push({ entry, name: reportedName(store, entry) });\n if (root.seen.length === 2) {\n emitTransactionEvent({\n type: 'sqlstack.transaction.multi_database',\n databases: root.seen.map((s) => s.name),\n });\n }\n }\n\n // First opened inside a nested scope: every enclosing nested scope gets\n // its savepoint right after BEGIN, outermost first.\n const chain: TxScope[] = [];\n for (let s: TxScope | undefined = scope; s && s.parent; s = s.parent) chain.unshift(s);\n for (const s of chain) await issueSavepoint(s, state);\n return state;\n })();\n\n root.opening.set(entry, open);\n try {\n return await open;\n } finally {\n root.opening.delete(entry);\n }\n}\n\n/**\n * @internal The transaction a query on `entry` runs in: the one already open\n * in this flow (including one a handle of the same database opened), or —\n * while a @transaction scope is active — one opened on that entry by the\n * query itself (on first execution, not on resolution). Undefined means \"run\n * on the database directly\".\n */\nexport function getTransactionTarget(entry: DatabaseEntry): ActiveTransaction | undefined {\n const store = getStore();\n const open = store ? findOpenTransaction(store, entry) : undefined;\n if (open) return open;\n const scope = activeScope(store);\n if (!store || !scope) return undefined;\n return {\n async query(sql: string, params: unknown[]): Promise<QueryResult> {\n if (scope.root.closed) return await entry.db.query(sql, params);\n const state = await openScopedTransaction(store, scope, entry);\n return await state.query(sql, params);\n },\n };\n}\n\n/**\n * @internal The transaction a query on a Database handle (run(db, ...)) runs\n * in. A transaction already open in this flow on that exact object is joined\n * (identity; registered or handle-opened). Inside a @transaction scope with\n * none open, the query opens one on the handle on first execution, exactly as\n * the name-resolved path does. Outside any scope the behaviour is unchanged:\n * join by identity or run directly (undefined).\n */\nexport function getTransactionTargetForHandle(db: { query(sql: string, params: unknown[]): Promise<unknown> }): ActiveTransaction | undefined {\n const store = getStore();\n if (!store) return undefined;\n for (const state of store.txByDb.values()) {\n if (state.db === db) return state;\n }\n const scope = activeScope(store);\n if (!scope) return undefined;\n return {\n async query(sql: string, params: unknown[]): Promise<QueryResult> {\n if (scope.root.closed) return (await db.query(sql, params)) as QueryResult;\n const state = await openScopedTransaction(store, scope, handleEntryFor(db));\n return await state.query(sql, params);\n },\n };\n}\n\nfunction dropFromStore(store: TxStore, state: TxState): void {\n if (store.txByDb.get(state.entry) === state) store.txByDb.delete(state.entry);\n}\n\nasync function runHooks(hooks: TransactionHook[]): Promise<{ failed: boolean; error: unknown }> {\n let failed = false;\n let error: unknown;\n for (const hook of hooks) {\n try {\n // Outside every scope: a hook that is itself @transaction opens a fresh one.\n await als.exit(() => hook());\n } catch (err) {\n if (!failed) {\n failed = true;\n error = err;\n }\n }\n }\n return { failed, error };\n}\n\n/** Roll back and release every transaction the root owns. Returns the first failure. */\nasync function rollbackOwned(root: TxScope, store: TxStore): Promise<{ failed: boolean; error: unknown }> {\n let failed = false;\n let error: unknown;\n for (const state of root.opened) {\n try {\n await state.rollbackIfStarted();\n } catch (err) {\n if (!failed) {\n failed = true;\n error = err;\n }\n } finally {\n try {\n await state.release();\n } catch (err) {\n if (!failed) {\n failed = true;\n error = err;\n }\n }\n dropFromStore(store, state);\n }\n }\n root.opened.length = 0;\n return { failed, error };\n}\n\nasync function exitRootOnSuccess(root: TxScope, store: TxStore): Promise<void> {\n // Name-based API compatibility: currentTransaction()?.rollbackOnly(err)\n // rolls everything back and throws, exactly as it does for withTransaction.\n const legacyMarked = root.opened.find((s) => s.rollbackOnly);\n if (legacyMarked) {\n const err = typeof legacyMarked.rollbackError !== 'undefined' ? legacyMarked.rollbackError : new RollbackTransactionError();\n await rollbackOwned(root, store);\n await runHooks(root.afterSettled);\n throw err;\n }\n\n let failed = false;\n let error: unknown;\n for (const state of root.opened) {\n try {\n if (failed || root.isMarked(state)) await state.rollbackIfStarted();\n else await state.commitIfStarted();\n } catch (err) {\n if (!failed) {\n failed = true;\n error = err;\n }\n } finally {\n try {\n await state.release();\n } catch (err) {\n if (!failed) {\n failed = true;\n error = err;\n }\n }\n dropFromStore(store, state);\n }\n }\n root.opened.length = 0;\n\n const commitHooks = !failed && !root.hasMarks ? await runHooks(root.afterCommit) : { failed: false, error: undefined };\n const settledHooks = await runHooks(root.afterSettled);\n if (failed) throw error;\n if (commitHooks.failed) throw commitHooks.error;\n if (settledHooks.failed) throw settledHooks.error;\n}\n\nasync function exitRootOnError(root: TxScope, store: TxStore): Promise<void> {\n await rollbackOwned(root, store);\n await runHooks(root.afterSettled);\n}\n\nasync function exitNestedOnSuccess(scope: TxScope): Promise<void> {\n const parent = scope.parent!;\n try {\n for (const { state, name } of scope.savepoints) {\n if (state.completed) continue;\n if (scope.isMarked(state)) await state.query(`ROLLBACK TO SAVEPOINT ${name}`, []);\n await state.query(`RELEASE SAVEPOINT ${name}`, []);\n }\n if (!scope.hasMarks) parent.afterCommit.push(...scope.afterCommit);\n } finally {\n parent.afterSettled.push(...scope.afterSettled);\n }\n}\n\nasync function exitNestedOnError(scope: TxScope): Promise<void> {\n for (const { state, name } of scope.savepoints) {\n if (state.completed) continue;\n try {\n await state.query(`ROLLBACK TO SAVEPOINT ${name}`, []);\n await state.query(`RELEASE SAVEPOINT ${name}`, []);\n } catch {\n // the original error wins; the root rolls back everything if it propagates\n }\n }\n scope.parent!.afterSettled.push(...scope.afterSettled);\n}\n\nasync function runInScope<T>(fn: () => Promise<T>): Promise<T> {\n const outer = getStore();\n const parent = activeScope(outer);\n const scope = new TxScope(parent);\n const store: TxStore = { txByDb: outer?.txByDb ?? new Map(), scope };\n // Reserve synchronously, before yielding: a parent must see even queued children.\n const turn = parent?.reserveChild();\n\n try {\n if (turn) await turn.ready;\n return await als.run(store, async () => {\n let out: T;\n try {\n if (parent) {\n // Siblings enter one at a time, so releasing one cannot erase another's savepoint.\n for (const state of scope.root.opened) {\n if (!state.completed) await issueSavepoint(scope, state);\n }\n }\n out = await fn();\n } catch (err) {\n // Promise.all may reject while another child is still writing. Keep this\n // scope active until those children settle, then roll back their work too.\n await scope.waitForChildren();\n scope.closed = true;\n if (parent) {\n await exitNestedOnError(scope);\n throw err;\n }\n await exitRootOnError(scope, store);\n throw isRollbackTransactionError(err) ? unwrapRollbackCause(err) : err;\n }\n await scope.waitForChildren();\n scope.closed = true;\n if (parent) await exitNestedOnSuccess(scope);\n else await exitRootOnSuccess(scope, store);\n return out;\n });\n } finally {\n // Release only after savepoint cleanup and descendants, on success or failure.\n turn?.release();\n }\n}\n\nfunction matchOpenTransaction(scope: TxScope, target: string | object): TxState {\n const open = scope.root.opened.filter((s) => !s.completed);\n const state =\n typeof target === 'string'\n ? open.find((s) => !isHandleEntry(s.entry) && s.entry.name === target)\n : open.find((s) => s.db === target);\n if (!state) {\n throw new SqlStackError(\n typeof target === 'string'\n ? `transaction.rollback(\"${target}\"): no transaction is open on a database named \"${target}\" in this scope.`\n : 'transaction.rollback(db): no transaction is open on that database handle in this scope.'\n );\n }\n return state;\n}\n\n/**\n * Mark the innermost @transaction scope for rollback. Synchronous and\n * non-throwing for the method: SQL after it still runs inside the open\n * transaction; at scope exit the scope rolls back instead of committing and\n * the method's return value still reaches the caller. With a target (a\n * registered database name or a Database handle), only that database's open\n * transaction is marked.\n */\nfunction markRollback(target?: string | object): void {\n const scope = requireScope('rollback');\n if (typeof target === 'undefined') {\n scope.markAll = true;\n return;\n }\n scope.marked.add(matchOpenTransaction(scope, target));\n}\n\n/**\n * Roll back everything the innermost scope has done so far, now. The root\n * scope rolls back and releases its transactions (the next query opens fresh\n * ones); a nested scope rolls back to its savepoints. Marks and the scope's\n * pending afterCommit hooks are cleared; afterSettled hooks stay.\n */\nasync function restartScope(): Promise<void> {\n const scope = requireScope('restart');\n const store = getStore()!;\n if (scope.parent) {\n for (const { state, name } of scope.savepoints) {\n if (state.completed) continue;\n await state.query(`ROLLBACK TO SAVEPOINT ${name}`, []);\n }\n } else {\n const result = await rollbackOwned(scope, store);\n if (result.failed) throw result.error;\n }\n scope.markAll = false;\n scope.marked.clear();\n scope.afterCommit = [];\n}\n\nfunction registerAfterCommit(fn: TransactionHook): void {\n if (typeof fn !== 'function') throw new SqlStackError('transaction.afterCommit(fn) requires a function.');\n requireScope('afterCommit').afterCommit.push(fn);\n}\n\nfunction registerAfterSettled(fn: TransactionHook): void {\n if (typeof fn !== 'function') throw new SqlStackError('transaction.afterSettled(fn) requires a function.');\n requireScope('afterSettled').afterSettled.push(fn);\n}\n\nexport type TransactionDecorator = {\n (target: any, prop: string | symbol, desc: PropertyDescriptor): void;\n (options?: TransactionOptions): (target: any, prop: string | symbol, desc: PropertyDescriptor) => void;\n /**\n * Mark the innermost scope (or, with a database name or handle, only that\n * database's open transaction) for rollback at scope exit. Never throws\n * inside a scope for a valid target; throws SqlStackError outside any\n * scope or when no open transaction matches the target.\n */\n rollback(target?: string | object): void;\n /** Roll back the scope's work now; the next query opens fresh transactions. */\n restart(): Promise<void>;\n /** Run fn after the root scope commits (dropped on rollback). */\n afterCommit(fn: TransactionHook): void;\n /** Run fn after the root scope finishes, committed or not. */\n afterSettled(fn: TransactionHook): void;\n};\n\nconst transactionDecorator = function (...args: any[]) {\n // @transaction\n if (args.length === 3 && typeof args[2]?.value === 'function') {\n const [target, prop, desc] = args as [any, string | symbol, PropertyDescriptor];\n wrapMethod(target, prop, desc, undefined);\n return;\n }\n // @transaction() or @transaction({ ... })\n const options: TransactionOptions | undefined = args.length > 0 ? args[0] : undefined;\n return function (target: any, prop: string | symbol, desc: PropertyDescriptor) {\n wrapMethod(target, prop, desc, options);\n };\n};\n\nexport const transaction: TransactionDecorator = Object.assign(transactionDecorator, {\n rollback: markRollback,\n restart: restartScope,\n afterCommit: registerAfterCommit,\n afterSettled: registerAfterSettled,\n}) as any;\n\n/**\n * A name (`{ db }`) or an eager open (`lazy: false`) keeps the name-based\n * behaviour of withTransaction. Everything else is a scope: no entry is\n * resolved; queries open transactions on first touch.\n */\nfunction isNameBased(options: TransactionOptions | undefined): boolean {\n return typeof options?.db !== 'undefined' || options?.lazy === false;\n}\n\nfunction wrapMethod(_target: any, _prop: string | symbol, desc: PropertyDescriptor, options?: TransactionOptions) {\n const original = desc.value;\n if (isNameBased(options)) {\n desc.value = async function (...callArgs: any[]) {\n return await withTransaction(() => original.apply(this, callArgs), options);\n };\n return;\n }\n desc.value = async function (...callArgs: any[]) {\n return await runInScope(() => original.apply(this, callArgs));\n };\n}\n\nexport type ActiveTransaction = {\n query(sql: string, params: unknown[]): Promise<QueryResult>;\n};\n\nexport function getActiveTransaction(entry: DatabaseEntry): ActiveTransaction | undefined {\n const store = getStore();\n return store?.txByDb.get(entry);\n}\n\n/**\n * Active transaction whose registered database is exactly `db` (object\n * identity), if any. `run(db, ...)` uses this so a handle passed at call time\n * joins a transaction opened on the same database (by `@transaction` or\n * `withTransaction`) instead of bypassing it. A handle that was never\n * registered with a SqlStack (or the legacy registry) never matches.\n */\nexport function getActiveTransactionForDatabase(db: object): ActiveTransaction | undefined {\n const store = getStore();\n if (!store) return undefined;\n for (const state of store.txByDb.values()) {\n if (state.db === db) return state;\n }\n return undefined;\n}\n"]}
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -909,28 +909,30 @@ Available error classes:
|
|
|
909
909
|
|
|
910
910
|
## Transactions
|
|
911
911
|
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
### Basic Usage with `@transaction` Decorator
|
|
915
|
-
|
|
916
|
-
Mark a method with `@transaction` to wrap it in a transaction:
|
|
912
|
+
`@transaction` on a method means *everything this method touches is transactional*. You don't name a database: each repository already knows its own (`@QueryBinder({ db })`, the stack default, or the active family binding).
|
|
917
913
|
|
|
918
914
|
```ts
|
|
919
|
-
import { transaction
|
|
915
|
+
import { transaction } from "sqlstack";
|
|
920
916
|
|
|
921
|
-
class
|
|
917
|
+
class SpawnService {
|
|
922
918
|
@transaction
|
|
923
|
-
async
|
|
924
|
-
await this.
|
|
925
|
-
await this.
|
|
919
|
+
async commitSpawnIdentity(input: Input): Promise<Spawned | SpawnRejected> {
|
|
920
|
+
const root = await this.agents.ensureRoot({ conversationId: input.rootConversationId });
|
|
921
|
+
await this.agents.insertRunning({ agentId: input.agentId, parentId: root.id });
|
|
922
|
+
|
|
923
|
+
if (input.group && !(await this.groups.canJoin(input.group.id))) {
|
|
924
|
+
transaction.rollback(); // mark; nothing is sent yet
|
|
925
|
+
await this.agents.recordRejection({ agentId: input.agentId }); // still runs, still visible here
|
|
926
|
+
return { rejected: true }; // returns normally; everything rolls back
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
transaction.afterCommit(() => this.publishSpawned(input)); // runs only if the commit lands
|
|
930
|
+
return { agentId: input.agentId, rootId: root.id }; // return → commit
|
|
926
931
|
}
|
|
927
932
|
}
|
|
928
|
-
|
|
929
|
-
// If either insert fails, both are rolled back
|
|
930
|
-
await new UserService().createUserWithProfile({ email: "alice@example.com", name: "Alice" });
|
|
931
933
|
```
|
|
932
934
|
|
|
933
|
-
Queries
|
|
935
|
+
Queries from `@Query` methods take part automatically. So do `run(sql...)` and `run("name", ...)`:
|
|
934
936
|
|
|
935
937
|
```ts
|
|
936
938
|
@QueryBinder()
|
|
@@ -940,179 +942,118 @@ class UsersRepo {
|
|
|
940
942
|
return run();
|
|
941
943
|
}
|
|
942
944
|
}
|
|
943
|
-
|
|
944
|
-
@QueryBinder()
|
|
945
|
-
class ProfilesRepo {
|
|
946
|
-
@Query({ sql: 'INSERT INTO profiles (user_id, bio) VALUES (:userId, :bio)' })
|
|
947
|
-
async insert(data: { userId: string; bio: string }): Promise<WriteResult> {
|
|
948
|
-
return run();
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
945
|
```
|
|
952
946
|
|
|
953
|
-
###
|
|
947
|
+
### Rules
|
|
948
|
+
|
|
949
|
+
1. **Opened on first touch.** Nothing is opened when the method starts. The first query that resolves to a database with no open transaction in this flow opens one on that database: `BEGIN IMMEDIATE` on SQLite, `BEGIN` on a pooled Postgres client, `START TRANSACTION` on a pooled MySQL connection. A `@transaction` method that issues no SQL opens nothing.
|
|
950
|
+
2. **Return commits, throw rolls back.** If the method returns normally, every transaction the scope opened is committed, in the order they were opened. If it throws, they are all rolled back and the error is rethrown.
|
|
951
|
+
3. **`transaction.rollback()` is a mark, not a throw.** The call is synchronous and marks the innermost scope. SQL after it still runs inside the open transaction and is visible to the method. When the method returns, the scope rolls back instead of committing, and the return value still reaches the caller. Pass a database name or a `Database` handle (`transaction.rollback("analytics")`, `transaction.rollback(analyticsDb)`) to mark only that database. The target must have a transaction open in the current flow; otherwise `SqlStackError` is thrown.
|
|
952
|
+
4. **`await transaction.restart()`.** This rolls back everything the scope has done so far, right away, and fresh transactions open on the next touch. Use it when the work after a failure must persist, such as writing a rejection record after a failed statement. It is the only portable form after a *failed statement* on Postgres, where the whole transaction is aborted until `ROLLBACK`. `afterCommit` hooks registered before the restart are dropped; `afterSettled` hooks stay.
|
|
953
|
+
5. **Nesting uses savepoints.** A `@transaction` method called from inside another one is a piece of the outer one. On entry it issues `SAVEPOINT` on every transaction already open, and a transaction first opened inside it gets its savepoint right after `BEGIN`. An inner `rollback()`, or an inner throw, becomes `ROLLBACK TO SAVEPOINT` and the outer scope continues. Inner success becomes `RELEASE SAVEPOINT`, and the inner `afterCommit` hooks move up to the outermost scope. The savepoint statements are the same on SQLite, Postgres and MySQL.
|
|
954
|
+
6. **Hooks.** `transaction.afterCommit(fn)` runs `fn` after the outermost scope commits, in registration order; it is dropped on rollback or on any mark. `transaction.afterSettled(fn)` runs after the outermost scope finishes either way, which makes it the place for cleanup. Hooks run *outside* the scope, so a hook that is itself `@transaction` opens a fresh, independent scope. A hook that throws makes the method's promise reject after all hooks have run; the commit has already happened by then.
|
|
955
|
+
7. **Two databases are coordinated, not atomic.** Both commit at return and both roll back on a mark. A failure between the two commits, however, leaves them inconsistent. When a scope opens its second database it emits one `sqlstack.transaction.multi_database` event with the database names, so these cases are visible. Cross-database side effects that must not be half-applied belong in `afterCommit`.
|
|
956
|
+
8. **SQLite queues.** Independent async flows that open a transaction on the same SQLite connection wait their turn instead of failing with "cannot start a transaction within a transaction". Postgres and MySQL get isolation from the pool and need no queue.
|
|
954
957
|
|
|
955
|
-
|
|
958
|
+
`transaction.rollback`, `transaction.restart`, `transaction.afterCommit` and `transaction.afterSettled` throw `SqlStackError` when called outside a `@transaction` method.
|
|
956
959
|
|
|
957
|
-
|
|
960
|
+
### Nested Scopes
|
|
958
961
|
|
|
959
962
|
```ts
|
|
960
963
|
class UserService {
|
|
961
964
|
@transaction
|
|
962
|
-
async createUser() {
|
|
963
|
-
await this.usersRepo.insert({ email
|
|
964
|
-
|
|
965
|
-
|
|
965
|
+
async createUser(email: string) {
|
|
966
|
+
await this.usersRepo.insert({ email });
|
|
967
|
+
await this.createDefaultProfile(); // SAVEPOINT … RELEASE SAVEPOINT
|
|
968
|
+
await this.usersRepo.markReady({ email });
|
|
966
969
|
}
|
|
967
|
-
}
|
|
968
|
-
|
|
969
|
-
await new UserService().createUser(); // throws "something went wrong"
|
|
970
|
-
```
|
|
971
|
-
|
|
972
|
-
### Lazy Transactions
|
|
973
970
|
|
|
974
|
-
By default, transactions use **lazy mode**: they don't start (no `BEGIN`) until the first query runs. This avoids overhead if the method never queries:
|
|
975
|
-
|
|
976
|
-
```ts
|
|
977
|
-
@transaction({ lazy: true }) // default behavior
|
|
978
|
-
async readOnlyOperation() {
|
|
979
|
-
// No database transaction started yet
|
|
980
|
-
const data = await this.repo.fetch();
|
|
981
|
-
|
|
982
|
-
// Process data without holding a transaction
|
|
983
|
-
return processData(data);
|
|
984
|
-
}
|
|
985
|
-
```
|
|
986
|
-
|
|
987
|
-
Disable lazy mode with `lazy: false` to start the transaction immediately:
|
|
988
|
-
|
|
989
|
-
```ts
|
|
990
|
-
@transaction({ lazy: false })
|
|
991
|
-
async mustStartTransaction() {
|
|
992
|
-
// BEGIN is executed immediately, even before first query
|
|
993
|
-
}
|
|
994
|
-
```
|
|
995
|
-
|
|
996
|
-
### Accessing the Current Transaction
|
|
997
|
-
|
|
998
|
-
Use `currentTransaction()` to access the active transaction context within a method:
|
|
999
|
-
|
|
1000
|
-
```ts
|
|
1001
|
-
class UserService {
|
|
1002
971
|
@transaction
|
|
1003
|
-
async
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
// Validate user was inserted
|
|
1007
|
-
const check = await this.usersRepo.findById(user.id);
|
|
1008
|
-
if (!check) {
|
|
1009
|
-
// Mark transaction for rollback and throw a custom error
|
|
1010
|
-
currentTransaction()?.rollbackOnly(new Error("User not found after insert"));
|
|
1011
|
-
return; // exit gracefully
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
return user;
|
|
972
|
+
async createDefaultProfile() {
|
|
973
|
+
await this.profilesRepo.insert({ name: "Default Profile" });
|
|
974
|
+
if (await this.profilesRepo.isDuplicate()) transaction.rollback(); // undoes only this piece
|
|
1015
975
|
}
|
|
1016
976
|
}
|
|
1017
977
|
```
|
|
1018
978
|
|
|
1019
|
-
###
|
|
1020
|
-
|
|
1021
|
-
Use `rollbackOnly(error)` to mark a transaction for rollback while specifying which error should be thrown:
|
|
979
|
+
### Restart After a Failed Statement
|
|
1022
980
|
|
|
1023
981
|
```ts
|
|
1024
|
-
class
|
|
982
|
+
class JoinService {
|
|
1025
983
|
@transaction
|
|
1026
|
-
async
|
|
984
|
+
async join(input: JoinInput) {
|
|
1027
985
|
try {
|
|
1028
|
-
await this.
|
|
1029
|
-
} catch (
|
|
1030
|
-
//
|
|
1031
|
-
|
|
1032
|
-
return
|
|
986
|
+
await this.members.insert(input);
|
|
987
|
+
} catch (err) {
|
|
988
|
+
await transaction.restart(); // the failed work is gone
|
|
989
|
+
await this.rejections.insert({ id: input.id }); // this persists
|
|
990
|
+
return { joined: false };
|
|
1033
991
|
}
|
|
992
|
+
return { joined: true };
|
|
1034
993
|
}
|
|
1035
994
|
}
|
|
1036
995
|
```
|
|
1037
996
|
|
|
1038
|
-
|
|
997
|
+
### Observing Multi-Database Scopes
|
|
1039
998
|
|
|
1040
999
|
```ts
|
|
1041
|
-
import {
|
|
1042
|
-
|
|
1043
|
-
class UserService {
|
|
1044
|
-
@transaction
|
|
1045
|
-
async createUser(email: string) {
|
|
1046
|
-
await this.usersRepo.insert({ email });
|
|
1000
|
+
import { onTransactionEvent } from "sqlstack";
|
|
1047
1001
|
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
}
|
|
1002
|
+
const unsubscribe = onTransactionEvent((event) => {
|
|
1003
|
+
// { type: "sqlstack.transaction.multi_database", databases: ["primary", "analytics"] }
|
|
1004
|
+
logger.warn(event.type, { databases: event.databases });
|
|
1005
|
+
});
|
|
1053
1006
|
```
|
|
1054
1007
|
|
|
1055
|
-
###
|
|
1008
|
+
### Name-Based Transactions (`@transaction({ db })`, `withTransaction`)
|
|
1056
1009
|
|
|
1057
|
-
|
|
1010
|
+
The name-based form from earlier versions still works as it always has. It opens a transaction on one named database only, and queries on other databases run outside it:
|
|
1058
1011
|
|
|
1059
1012
|
```ts
|
|
1060
|
-
import { withTransaction } from "sqlstack";
|
|
1061
|
-
|
|
1062
|
-
const result = await withTransaction(async () => {
|
|
1063
|
-
const user = await this.usersRepo.insert({ email: "charlie@example.com" });
|
|
1064
|
-
await this.profilesRepo.insert({ userId: user.id });
|
|
1065
|
-
return user;
|
|
1066
|
-
}, { db: "primary" });
|
|
1067
|
-
```
|
|
1013
|
+
import { transaction, withTransaction, currentTransaction, RollbackTransactionError } from "sqlstack";
|
|
1068
1014
|
|
|
1069
|
-
### Multiple Databases
|
|
1070
|
-
|
|
1071
|
-
Transactions are per-database. Run transactions on different databases simultaneously:
|
|
1072
|
-
|
|
1073
|
-
```ts
|
|
1074
1015
|
class MultiDbService {
|
|
1075
|
-
@transaction({ db: "primary" })
|
|
1016
|
+
@transaction({ db: "primary" }) // lazy: BEGIN on the first query to "primary"
|
|
1076
1017
|
async insertUser() {
|
|
1077
1018
|
await this.usersRepo.insert({ email: "dave@example.com" });
|
|
1078
1019
|
}
|
|
1079
1020
|
|
|
1080
|
-
@transaction({ db: "
|
|
1081
|
-
async
|
|
1082
|
-
await this.analyticsRepo.insert({ event: "user_created" });
|
|
1083
|
-
}
|
|
1021
|
+
@transaction({ db: "primary", lazy: false }) // BEGIN immediately
|
|
1022
|
+
async mustStart() {}
|
|
1084
1023
|
}
|
|
1085
1024
|
|
|
1086
|
-
|
|
1087
|
-
await
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1025
|
+
const result = await withTransaction(async () => {
|
|
1026
|
+
const user = await this.usersRepo.insert({ email: "charlie@example.com" });
|
|
1027
|
+
await this.profilesRepo.insert({ userId: user.id });
|
|
1028
|
+
return user;
|
|
1029
|
+
}, { db: "primary" });
|
|
1091
1030
|
```
|
|
1092
1031
|
|
|
1093
|
-
|
|
1032
|
+
On SQLite this form issues a plain `BEGIN` and doesn't queue. `@transaction({ lazy: false })` with no `db` opens eagerly on the default database.
|
|
1094
1033
|
|
|
1095
|
-
|
|
1034
|
+
`currentTransaction()?.rollbackOnly(error?)` marks the active transaction for rollback *and throws* at exit: it throws `error` if one was given, otherwise `RollbackTransactionError`. Throwing `new RollbackTransactionError(message, cause)` rolls back and rethrows `cause`. Both work inside a scope-based `@transaction` too:
|
|
1096
1035
|
|
|
1097
1036
|
```ts
|
|
1098
1037
|
class UserService {
|
|
1099
1038
|
@transaction
|
|
1100
1039
|
async createUser(email: string) {
|
|
1101
|
-
|
|
1102
|
-
|
|
1040
|
+
try {
|
|
1041
|
+
await this.usersRepo.insert({ email });
|
|
1042
|
+
} catch {
|
|
1043
|
+
currentTransaction()?.rollbackOnly(new Error("Failed to create user")); // caller sees this error
|
|
1044
|
+
return;
|
|
1045
|
+
}
|
|
1103
1046
|
}
|
|
1104
1047
|
|
|
1105
|
-
@transaction
|
|
1106
|
-
async
|
|
1107
|
-
await this.
|
|
1048
|
+
@transaction
|
|
1049
|
+
async cancel(email: string) {
|
|
1050
|
+
await this.usersRepo.insert({ email });
|
|
1051
|
+
throw new RollbackTransactionError("Transaction cancelled", new Error("User rejected")); // caller sees "User rejected"
|
|
1108
1052
|
}
|
|
1109
1053
|
}
|
|
1110
|
-
|
|
1111
|
-
// Outer transaction commits both inserts
|
|
1112
|
-
await new UserService().createUser("eve@example.com");
|
|
1113
1054
|
```
|
|
1114
1055
|
|
|
1115
|
-
|
|
1056
|
+
When code is mixed, a name-based transaction that is open in the flow is joined by queries on that database. The name-based transaction keeps its own commit and rollback rules: a scope's `rollback()` mark or `restart()` doesn't apply to it.
|
|
1116
1057
|
|
|
1117
1058
|
### Connection Pooling and Resource Cleanup
|
|
1118
1059
|
|