u
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user