【问题标题】:Node-Firebird Invalid transaction handleNode-Firebird 无效的事务句柄
【发布时间】:2020-11-24 19:42:09
【问题描述】:

尝试按顺序提交同一事务时出现错误。 我正在使用 Node-firebird 库。 第一次提交,但第二次我收到以下消息:

错误:

> 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

当我收到相同事务的错误消息时,我正在尝试插入 CHILDREN。

    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);
            });
        });
}

【问题讨论】:

  • 显示您创建交易的代码。特别是 transaction 变量的初始化位置。
  • @tbking 更新了该信息。
  • "尝试使用相同的事务按顺序提交" - 我不特别了解 firebase,但我怀疑这在任何数据库中都是可能的。
  • 请提供minimal reproducible example。我的猜测是,您正在尝试在事务句柄已提交后重用它,但鉴于您没有显示对这些插入方法等的实际调用,这只是一个猜测。如果提交事务,则需要获取新的事务句柄。
  • @Bergi 在 Firebird 中有 commit retainingrollback retaining 操作(不是无关的 Google Firebase),但它们肯定是不经常使用的特殊情况。例如,我认为我个人从未使用过它们。毫无疑问,正常的期望是结束交易就​​是结束交易。

标签: javascript node.js firebird node-firebird


【解决方案1】:

您似乎正试图在多个函数调用中重用事务。尝试这样做:

const db = await FirebirdPromise.attach();
transaction = await this.getTransaction(db);

您应该每次都生成事务然后提交,而不是从参数中获取事务并多次提交。对于下一次插入,生成另一个事务。

【讨论】:

  • 或者,OP 应该生成一个事务,并为每个插入传递它,并且只有在所有插入完成时才提交。
  • 同意,以上代码更改是基于共享的代码。我很确定在给定足够的上下文的情况下有更好的方法来做到这一点。不过我会把它留给 OP 去寻找最好的方法。
猜你喜欢
  • 2019-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多