【问题标题】:conn.commitAsync is not a function error when running as transactionconn.commitAsync 作为事务运行时不是函数错误
【发布时间】:2021-03-17 00:10:27
【问题描述】:

当我运行以下代码时,我不断收到此错误:

TypeError: conn.commitAsync is not a function
    at Oracle_Transaction.commit (/home/foo/node_modules/knex/lib/dialects/oracledb/transaction.js:14:18)
    at Function.transactor.commit (/home/foo/node_modules/knex/lib/transaction.js:277:40)
    at /home/foo/node_modules/knex/lib/transaction.js:191:35

如果我在没有事务的情况下运行,我似乎没有问题,所以我假设它是被阻塞的隐式提交。顺便说一句,这经常运行良好,只有当我尝试模拟它时才会失败。

我错过了什么吗?是否是未模拟的连接,如果这是问题,我该如何模拟它?

import * as knex from 'knex';

export const pool: any = knex({
    acquireConnectionTimeout: 60000,
    client: 'oracledb',
    connection: {
        connectString: 'zoo',
        password: 'foo',
        user: 'bar',
    },
    debug: true,
    pool: {
        acquireTimeoutMillis: 60000, 10),
        idleTimeoutMillis: 60000,
        max: 10,
        min: 10,
    },
});

    await pool.transaction((trx: any) => {
        return Promise.all([
            row = this.insertOne(trx, id, data),
            this.insertTwo(trx, id, data),
            userData.flag ? this.insertThree(trx, id, data) : {},
            this.insertFour(trx, id, data),
            moreToDo(data),
        ]);
    })
    .catch((err: any) => {
        logger.error(err);
    });

每个插入函数看起来都像这样

    public insertOne(trx: any,  id: number, data: any) {
    return pool('FOOBAR')
            .transacting(trx)
            .withSchema('FOO')
            .insert([
                {
                    FOO: 'BAR',
                    ID: id,
                    CREATE_DT: pool.raw('sysdate'),
                    LAST_MOD_DT: pool.raw('sysdate'),
                },
            ]);
}

被嘲笑成这样

import * as mockKnex from 'mock-knex';
mockKnex.mock(pool);
const tracker = mockKnex.getTracker();
tracker.install();
    tracker.on('query', (query, step) => {
        [
            function firstQuery() {
                    {
                        ID: 1234,
                    },
                ]);
            },
            function secondQuery() {
                query.response([
                    {
                        ID: 1234,
                    },
                ]);
            },
            function thirdQuery() {
                query.response([]);
            },
            function fourthQuery() {
                query.response([]);
            },
            function fifthQuery() {
                query.response([]);
            },
        ][step - 1]();
    });
    const results = await sut.inserts(subject);
    expect(results).toEqual(foo);

我也尝试过使用嵌套的 .then 语句,就像 knex 文档使用显式提交或回滚一样,同样的问题。

【问题讨论】:

  • 即使它在未模拟时运行“正常”,请确保您了解为什么不建议在单个连接上使用 Promise.all(如果这是 Knex 正在做的),请参阅 node-oracledb doc
  • 这是否也适用于池?即,即使使用池,它也只会在单个连接上运行吗?我的猜测是,模拟库(mock-knex)在使用事务时没有正确模拟池中的连接。那里有更好的图书馆吗?
  • 连接就是连接,是的,它适用于池。

标签: node.js mocking knex.js node-oracledb


【解决方案1】:

对于遇到相同问题的任何人,我可以通过在 oracledb 的 Transaction 类中的回滚和提交函数上添加一个 jest.spyOn 来解决这个问题

// tslint:disable: no-var-requires
// tslint:disable: no-require-imports
// tslint:disable-next-line: variable-name
const Transaction  = require('../../node_modules/knex/lib/dialects/oracledb/transaction.js');

const rollbackMock = jest.spyOn(Transaction.prototype, 'rollback');
const commitkMock = jest.spyOn(Transaction.prototype, 'commit');

在 beforeEach() 中

jest.resetAllMocks();
rollbackMock.mockImplementation(() => null);
commitkMock.mockImplementation(() => null);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    • 2021-10-14
    • 1970-01-01
    • 1970-01-01
    • 2018-11-04
    • 1970-01-01
    • 2023-01-25
    相关资源
    最近更新 更多