This commit is contained in:
seb
2026-10-16 01:59:11 +02:00
parent 0d726c76f8
commit fcbcb243e3

View File

@@ -6,9 +6,12 @@
*/ */
import Database from 'better-sqlite3'; import Database from 'better-sqlite3';
import { AsyncLocalStorage } from 'node:async_hooks';
import { logSlowQuery } from '../provider.js'; import { logSlowQuery } from '../provider.js';
import { SCHEMA_SCRIPTS } from './schema.js'; import { SCHEMA_SCRIPTS } from './schema.js';
const asyncTxStorage = new AsyncLocalStorage();
function normalizeParamValue(value) { function normalizeParamValue(value) {
if (value === undefined || value === null) return null; if (value === undefined || value === null) return null;
if (value instanceof Date) { if (value instanceof Date) {
@@ -324,6 +327,7 @@ export class BetterSqlite3Provider extends BetterSqlite3Executor {
this.pool = this; this.pool = this;
db.pragma('foreign_keys = ON'); db.pragma('foreign_keys = ON');
db.pragma('journal_mode = WAL'); db.pragma('journal_mode = WAL');
db.pragma('synchronous = NORMAL');
db.pragma('busy_timeout = 5000'); db.pragma('busy_timeout = 5000');
} }
@@ -366,8 +370,9 @@ export class BetterSqlite3Provider extends BetterSqlite3Executor {
return runner; return runner;
}; };
if (this.#transactionDepth > 0 || this.db.inTransaction) { const activeContext = asyncTxStorage.getStore();
const savepoint = `sp_${++this.#transactionDepth}`; if (activeContext) {
const savepoint = `sp_${++activeContext.depth}`;
this.db.exec(`SAVEPOINT ${savepoint}`); this.db.exec(`SAVEPOINT ${savepoint}`);
const executor = new BetterSqlite3Executor(this.db, this.storageDir); const executor = new BetterSqlite3Executor(this.db, this.storageDir);
const runner = bindRunner(executor); const runner = bindRunner(executor);
@@ -376,8 +381,12 @@ export class BetterSqlite3Provider extends BetterSqlite3Executor {
.then(() => fn(runner, executor)) .then(() => fn(runner, executor))
.then( .then(
(result) => { (result) => {
this.db.exec(`RELEASE SAVEPOINT ${savepoint}`); try {
this.#transactionDepth--; this.db.exec(`RELEASE SAVEPOINT ${savepoint}`);
} catch {
// ignore if outer transaction already rolled back
}
activeContext.depth--;
return result; return result;
}, },
(err) => { (err) => {
@@ -387,7 +396,7 @@ export class BetterSqlite3Provider extends BetterSqlite3Executor {
} catch { } catch {
// ignore // ignore
} }
this.#transactionDepth--; activeContext.depth--;
throw err; throw err;
}, },
); );
@@ -399,7 +408,7 @@ export class BetterSqlite3Provider extends BetterSqlite3Executor {
try { try {
const executor = new BetterSqlite3Executor(this.db, this.storageDir); const executor = new BetterSqlite3Executor(this.db, this.storageDir);
const runner = bindRunner(executor); const runner = bindRunner(executor);
const result = await fn(runner, executor); const result = await asyncTxStorage.run({ depth: 0 }, () => fn(runner, executor));
this.db.exec('COMMIT'); this.db.exec('COMMIT');
return result; return result;
} catch (err) { } catch (err) {