Skip to content

Commit 2cd06e4

Browse files
committed
Added test reproducing the parallel transaction failure
1 parent 1000450 commit 2cd06e4

1 file changed

Lines changed: 61 additions & 0 deletions

File tree

src/packages/dumbo/src/storage/sqlite/sqlite3/transactions/transactions.int.spec.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,67 @@ describe('SQLite3 Transactions', () => {
552552
}
553553
});
554554

555+
// TODO: parallel pool.withTransaction calls share one underlying SQLite
556+
// transaction on the singleton writer connection. A rollback in one
557+
// sibling rolls back the other's writes. Fix requires a writer queue
558+
// (one real BEGIN/COMMIT per call), not just the finally-block tweak.
559+
it.fails(
560+
`isolates a failing parallel transaction from a successful one with ${testName} database`,
561+
async () => {
562+
const pool = sqlite3Pool({
563+
fileName,
564+
transactionOptions: { allowNestedTransactions: true },
565+
});
566+
567+
try {
568+
await pool.execute.command(
569+
SQL`CREATE TABLE isolation_test (id INTEGER PRIMARY KEY, value TEXT)`,
570+
);
571+
572+
let releaseA: () => void = () => {};
573+
let releaseB: () => void = () => {};
574+
const aMayProceed = new Promise<void>((r) => {
575+
releaseA = r;
576+
});
577+
const bMayProceed = new Promise<void>((r) => {
578+
releaseB = r;
579+
});
580+
581+
const a = pool.withTransaction(async (tx) => {
582+
await tx.execute.command(
583+
SQL`INSERT INTO isolation_test (id, value) VALUES (1, 'a-commits')`,
584+
);
585+
releaseB();
586+
await aMayProceed;
587+
});
588+
589+
const b = pool.withTransaction(async (tx) => {
590+
await bMayProceed;
591+
await tx.execute.command(
592+
SQL`INSERT INTO isolation_test (id, value) VALUES (2, 'b-rolls-back')`,
593+
);
594+
throw new Error('B intentional failure');
595+
});
596+
597+
await assert.rejects(b, /B intentional failure/);
598+
releaseA();
599+
await a;
600+
601+
const rows = await pool.execute.query<{
602+
id: number;
603+
value: string;
604+
}>(SQL`SELECT id, value FROM isolation_test ORDER BY id`);
605+
606+
assert.deepStrictEqual(
607+
rows.rows.map((r) => r.value),
608+
['a-commits'],
609+
);
610+
} finally {
611+
await pool.close();
612+
}
613+
},
614+
);
615+
555616
it(`serializes concurrent withConnection writes with ${testName} database`, async () => {
556617
const pool = sqlite3Pool({
557618
fileName,

0 commit comments

Comments
 (0)