Skip to content

Commit 436ba56

Browse files
committed
Fix lock not working for multiple transactions started at the same time
1 parent 905667c commit 436ba56

2 files changed

Lines changed: 48 additions & 7 deletions

File tree

example/src/tests/rawQueries.spec.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,46 @@ export function registerBaseTests() {
391391
}, 1000);
392392
});
393393

394+
it('Async transaction, upsert and select', done => {
395+
// ARRANGE: Setup for multiple transactions
396+
const iterations = 10;
397+
const actual = new Set();
398+
399+
// ARRANGE: Generate expected data
400+
const id = chance.integer();
401+
const name = chance.name();
402+
const age = chance.integer();
403+
404+
// ACT: Start multiple async transactions to upsert and select the same record
405+
for (let iteration = 1; iteration <= iterations; iteration++) {
406+
db.transactionAsync(async (tx) => {
407+
// ACT: Upsert statement to create record / increment the value
408+
await tx.executeAsync(`
409+
INSERT OR REPLACE INTO [User] ([id], [name], [age], [networth])
410+
SELECT ?, ?, ?,
411+
IFNULL((
412+
SELECT [networth] + 1000
413+
FROM [User]
414+
WHERE [id] = ?
415+
), 1000)
416+
`, [id, name, age, id]);
417+
418+
// ACT: Select statement to get incremented value and store it for checking later
419+
const results = await tx.executeAsync('SELECT [networth] FROM [User] WHERE [id] = ?', [id]);
420+
421+
actual.add(results.rows._array[0].networth);
422+
})
423+
}
424+
425+
// ACT: Wait for all transactions to complete
426+
setTimeout(() => {
427+
// ASSERT: That the expected values where returned
428+
expect(actual.size).to.equal(iterations, 'Each transaction should read a different value');
429+
430+
done();
431+
}, 1000);
432+
});
433+
394434
it('Batch execute', () => {
395435
const id1 = chance.integer();
396436
const name1 = chance.name();

src/index.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -354,21 +354,22 @@ QuickSQLite.transactionAsync = (
354354
};
355355

356356
const startNextTransaction = (dbName: string) => {
357+
if (!locks[dbName]) {
358+
throw Error(`Lock not found for db: ${dbName}`);
359+
}
360+
357361
if (locks[dbName].inProgress) {
358362
// Transaction is already in process bail out
359363
return;
360364
}
361365

362-
setImmediate(() => {
363-
if (!locks[dbName]) {
364-
throw Error(`Lock not found for db: ${dbName}`);
365-
}
366-
367366
if (locks[dbName].queue.length) {
368367
locks[dbName].inProgress = true;
369-
locks[dbName].queue.shift().start();
370-
}
368+
const tx = locks[dbName].queue.shift();
369+
setImmediate(() => {
370+
tx.start();
371371
});
372+
}
372373
};
373374

374375
// _________ _______ ______ ____ _____ __ __ _____ _____

0 commit comments

Comments
 (0)