"Concurrent jobs in the same session are not allowed" error in transaction in one session
amoywolf opened this issue · comments
amoywolf commented
- What you're trying to do
Based on https://cloud.google.com/bigquery/docs/transactions, I try to handle a transaction in one session by using nodejs-bigquery library - What code you've already tried
import { BigQuery } from '@google-cloud/bigquery';
const tableName = 'modi_images.test';
export default class BigQuerySession {
bigqueryClient: BigQuery;
sessionId: string;
constructor() {
this.bigqueryClient = new BigQuery();
this.sessionId = '';
}
async openSession() {
const query = 'SELECT 1;';
const options = {
query,
createSession: true,
};
const [job] = await this.bigqueryClient.createQueryJob(options);
await job.getQueryResults(); // Wait for job completion
this.sessionId = job.metadata.statistics.sessionInfo.sessionId;
return this.sessionId;
}
async closeSession() {
if (this.sessionId) {
const query = 'CALL BQ.ABORT_SESSION();';
const options = {
query,
createSession: false,
connectionProperties: [
{
key: 'session_id',
value: this.sessionId,
},
],
};
const [job] = await this.bigqueryClient.createQueryJob(options);
await job.getQueryResults();
}
}
async executeQuery(query: string) {
const options = {
query,
createSession: false,
connectionProperties: [
{
key: 'session_id',
value: this.sessionId,
},
],
};
const [job] = await this.bigqueryClient.createQueryJob(options);
await job.getQueryResults();
}
async runBigQueryTransaction(scripts: string[]) {
if (!this.sessionId) {
await this.openSession();
}
try {
const beginTransactionQuery = 'BEGIN TRANSACTION;';
await this.executeQuery(beginTransactionQuery);
scripts.forEach(async (queryScript) => {
await this.executeQuery(queryScript);
});
const commitTransactionQuery = 'COMMIT TRANSACTION;';
await this.executeQuery(commitTransactionQuery);
} catch (error) {
console.error('Error:', error);
} finally {
await this.closeSession();
}
}
}
const scripts = [
`INSERT INTO ${tableName} VALUES (3, 'Alice', 35);`,
];
const session = new BigQuerySession();
session.runBigQueryTransaction(scripts);
- Any error messages you're getting
ApiError: Resources exceeded during query execution: Another job abc:US.1cefe6bf-adb3-48bf-983c-c8415f627fb4 is currently running in the session Ch4KHG1vZGlmYWNlLWNhbleHeWxpZ2h0LXNhbmRib3gQARokOTRjZjUyYmItHeOemS00M2Y4LTllYWUtNzE0NWQyM2UzMDFk. Concurrent jobs in the same session are not allowed.
at new ApiError (/Users/tommywang/modi-images/api/node_modules/@google-cloud/common/build/src/util.js:75:15)
at Util.parseHttpRespBody (/Users/tommywang/modi-images/api/node_modules/@google-cloud/common/build/src/util.js:210:38)
at Util.handleResp (/Users/tommywang/modi-images/api/node_modules/@google-cloud/common/build/src/util.js:151:117)
at /Users/tommywang/modi-images/api/node_modules/@google-cloud/common/build/src/util.js:534:22
at onResponse (/Users/tommywang/modi-images/api/node_modules/retry-request/index.js:240:7)
at /Users/tommywang/modi-images/api/node_modules/teeny-request/src/index.ts:333:11
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
code: 400,
errors: [
{
message: 'Resources exceeded during query execution: Another job modiface-candlelight-sandbox:US.1cefe6bf-adb3-48bf-983c-c8915f625fb4 is currently running in the session Ch4KHG1vZGlmYWNlLWNhbmRsZWxpZ2h0LXNhbmRib3gQARokOTRjZjUyYmItZmJkYS00M2Y4LTllYWUtNzE0NWQyM2UzMDFk. Concurrent jobs in the same session are not allowed.',
domain: 'global',
reason: 'resourcesExceeded'
}
],
amoywolf commented
Solved. The root cause is following forEach doesn't actually await.
scripts.forEach(async (queryScript) => {
await this.executeQuery(queryScript);
});
By changing to following, it works.
for (const queryScript of scripts) {
await this.executeQuery(queryScript);
}