Skip to content

Commit 1000450

Browse files
committed
Fixed current transaction cleanup for outer transaction
1 parent 18a4c93 commit 1000450

3 files changed

Lines changed: 67 additions & 37 deletions

File tree

src/packages/dumbo/src/storage/sqlite/core/transactions/index.ts

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -85,21 +85,18 @@ export const sqliteTransaction =
8585
commit: async function () {
8686
const client = (await getClient) as SQLiteClientOrPoolClient;
8787

88-
try {
89-
if (allowNestedTransactions) {
90-
if (transactionCounter.level > 1) {
91-
if (options?.useSavepoints) {
92-
await client.command(
93-
SQL`RELEASE transaction${SQL.plain(transactionCounter.level.toString())}`,
94-
);
95-
}
96-
transactionCounter.decrement();
97-
98-
return;
99-
}
100-
101-
transactionCounter.reset();
88+
if (allowNestedTransactions && transactionCounter.level > 1) {
89+
if (options?.useSavepoints) {
90+
await client.command(
91+
SQL`RELEASE transaction${SQL.plain(transactionCounter.level.toString())}`,
92+
);
10293
}
94+
transactionCounter.decrement();
95+
return;
96+
}
97+
98+
try {
99+
if (allowNestedTransactions) transactionCounter.reset();
103100
hasBegun = false;
104101
await client.command(SQL`COMMIT`);
105102
} finally {
@@ -111,14 +108,13 @@ export const sqliteTransaction =
111108
},
112109
rollback: async function (error?: unknown) {
113110
const client = (await getClient) as SQLiteClientOrPoolClient;
114-
try {
115-
if (allowNestedTransactions) {
116-
if (transactionCounter.level > 1) {
117-
transactionCounter.decrement();
118-
return;
119-
}
120-
}
121111

112+
if (allowNestedTransactions && transactionCounter.level > 1) {
113+
transactionCounter.decrement();
114+
return;
115+
}
116+
117+
try {
122118
hasBegun = false;
123119
await client.command(SQL`ROLLBACK`);
124120
} finally {

src/packages/dumbo/src/storage/sqlite/d1/transactions/d1Transaction.ts

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -90,31 +90,27 @@ export const d1Transaction =
9090
commit: async function () {
9191
const client = await getDatabaseClient();
9292

93-
try {
94-
if (allowNestedTransactions) {
95-
if (transactionCounter.level > 1) {
96-
transactionCounter.decrement();
97-
98-
return;
99-
}
93+
if (allowNestedTransactions && transactionCounter.level > 1) {
94+
transactionCounter.decrement();
95+
return;
96+
}
10097

101-
transactionCounter.reset();
102-
}
98+
try {
99+
if (allowNestedTransactions) transactionCounter.reset();
103100
sessionClient = null;
104101
} finally {
105102
if (options?.close) await options?.close(client);
106103
}
107104
},
108105
rollback: async function (error?: unknown) {
109106
const client = await getDatabaseClient();
110-
try {
111-
if (allowNestedTransactions) {
112-
if (transactionCounter.level > 1) {
113-
transactionCounter.decrement();
114-
return;
115-
}
116-
}
117107

108+
if (allowNestedTransactions && transactionCounter.level > 1) {
109+
transactionCounter.decrement();
110+
return;
111+
}
112+
113+
try {
118114
sessionClient = null;
119115
} finally {
120116
if (options?.close) await options?.close(client, error);

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,44 @@ describe('SQLite3 Transactions', () => {
7676
await pool.close();
7777
}
7878
});
79+
it('keeps the outer transaction open after a sibling nested transaction commits', async () => {
80+
const pool = sqlite3Pool({
81+
fileName,
82+
transactionOptions: { allowNestedTransactions: true },
83+
});
84+
85+
try {
86+
await pool.execute.command(
87+
SQL`CREATE TABLE test_table (id INTEGER PRIMARY KEY, value TEXT)`,
88+
);
89+
90+
await pool.withTransaction(async (outerTx) => {
91+
await pool.withTransaction(async (innerTx) => {
92+
await innerTx.execute.command(
93+
SQL`INSERT INTO test_table (id, value) VALUES (1, 'first')`,
94+
);
95+
});
96+
97+
await pool.withTransaction(async (innerTx) => {
98+
await innerTx.execute.command(
99+
SQL`INSERT INTO test_table (id, value) VALUES (2, 'second')`,
100+
);
101+
});
102+
103+
await outerTx.execute.command(
104+
SQL`INSERT INTO test_table (id, value) VALUES (3, 'outer')`,
105+
);
106+
});
107+
108+
const rows = await pool.execute.query<{ count: number }>(
109+
SQL`SELECT COUNT(*) as count FROM test_table`,
110+
);
111+
assert.strictEqual(rows.rows[0]?.count, 3);
112+
} finally {
113+
await pool.close();
114+
}
115+
});
116+
79117
it('should fail with an error if transaction nested is false', async () => {
80118
const pool = sqlite3Pool({
81119
fileName,

0 commit comments

Comments
 (0)