Reputation: 41
I got an error when trying to commit in sequence with the same transaction. I am using Node-firebird lib. The first time is committed, but the second time I got the following message:
Error:
> invalid transaction handle (expecting explicit transaction start) at
> doCallback
> (C:\Ultra\PreVendaServerV2\node_modules\node-firebird\lib\index.js:1297:21)
> at
> C:\Ultra\PreVendaServerV2\node_modules\node-firebird\lib\index.js:3019:25
> at
> C:\Ultra\PreVendaServerV2\node_modules\node-firebird\lib\messages.js:151:25
> at search
> (C:\Ultra\PreVendaServerV2\node_modules\node-firebird\lib\messages.js:117:13)
> at
> C:\Ultra\PreVendaServerV2\node_modules\node-firebird\lib\messages.js:54:21
> at FSReqCallback.wrapper [as oncomplete] (fs.js:520:5) at
> FSReqCallback.callbackTrampoline (internal/async_hooks.js:126:14) {
> gdscode: 335544332, gdsparams: undefined
I am trying to insert the CHILDREN when I get the error message with the same transaction.
public static async getTransaction(db: Database, ISOLATION_LEVEL?: number[]): Promise<Firebird.Transaction> {
if (!db) throw "There is no Connection with the database!";
const ISOLATION = ISOLATION_LEVEL ? ISOLATION_LEVEL : Firebird.ISOLATION_READ_COMMITED;
return new Promise(
(resolve, reject) => {
db.transaction(ISOLATION, function (err, transaction) {
if (err && LOG_SQL) { console.log(err) };
if (err) reject(err);
resolve(transaction);
});
});
}
public static async asyncInsert(insertSQL: string, params?: any[], insertChildrenCallback?: any, originObject?: any, transaction?: Firebird.Transaction, commit?: boolean) {
try {
const db = await FirebirdPromise.attach();
if (!transaction) transaction = await this.getTransaction(db);
const insertedId = await this.execQueryWithTransaction(insertSQL, transaction, params, originObject);
if (insertChildrenCallback) await insertChildrenCallback(insertedId, originObject, transaction, db);
if (commit) await this.tryCommit(transaction, db);
return new DatabaseResult({
status: DatabaseResult.RESULT_OK, message: null, data: insertedId
});
} catch (error) {
return new DatabaseResult({
status: DatabaseResult.RESULT_ERROR, message: error, data: null
});
}
}
public static async tryCommit(transaction: Firebird.Transaction, db: Database): Promise<Boolean> {
return new Promise(
(resolve, reject) => {
transaction.commit(function (err) {
if (err) {
if (LOG_SQL) console.log(err);
transaction.rollback();
reject(err);
throw err;
}
db.detach();
resolve(true);
});
});
}
Upvotes: 4
Views: 906
Reputation: 9096
It seems like you are trying to reuse a transaction in multiple function calls. Try doing this:
const db = await FirebirdPromise.attach();
transaction = await this.getTransaction(db);
Instead of getting transaction from the argument, and committing it multiple times, you should generate the transaction every time and then commit it. For the next insert, generate another transaction.
Upvotes: 1