-
Notifications
You must be signed in to change notification settings - Fork 112
Description
Transaction gets assigned to the session as per this ref.
Issue:
In a multiplexed architecture, a single session is reused to handle multiple transactions, creating a one-to-many relationship. While efficient, this model introduces a critical problem in a multithreaded environment.
The core issue is a race condition. When multiple threads operate in parallel, they share the same session object. As each thread initiates a new transaction, it overwrites a common transaction field (txn) within that shared session object.
Consequently, operations from one thread can be mistakenly executed within the context of a transaction started by a different thread. This leads to severe errors, including:
Incorrect transaction execution: Logic intended for one transaction is applied to another.
Erroneous commits: Data is committed to the database under the wrong transaction, leading to data corruption and inconsistent state within the client.
Steps to reproduce:
Run below script on multiple threads in parallel
await database.runTransactionAsync(async tx => {
const [rows] = await tx.run('SELECT * FROM Singers');
rows.forEach(row => {
const json = row.toJSON();
console.log(`SingerId: ${json.SingerId}, FullName: ${json.FullName}`);
});
const id = Math.floor(Math.random() * 10000) + 1;
const name = randomUUID();
tx.upsert('Singers', [{SingerId: id, FirstName: name}]);
await tx.commit();
console.log('transaction done.');
}
cc: @surbhigarg92