Why is my knex transaction throwing: Reference Error: <table> is not defined

Why is my knex transaction throwing: Reference Error: <table> is not defined

我正在使用交易方法完成我的第一笔 knex 交易。目的是让一组三个插入语句以原子方式将传入记录的数据保存到三个 table 中。对于上下文 - 传入记录表示具有两个 1:M 子关系的父对象 - "a material has 0 to many properties and a material has 0 to many notes." 所以我有一个材料关系,一个 material_properties 关系和一个 material_notes 关系。

我有一个不在事务中的方法版本。但是,当我尝试将功能包装在事务中时,如 Knex documentation - 'Transaction' section - 在 "Same example as above using another await/async approach:" 小节中指定的那样,我收到一个引用错误,指出未定义第一个子关系。此外,我得到一个

UnhandledPromiseRejectionWarning: ReferenceError: trx is not defined

注意:先插入父table,尝试插入第一个子table时出现引用错误:'material_properties'.

这是有效的方法:

const materialRecord = {
            name: material.name,
            description: material.description ? material.description : null,
            user_id: userId
        }

/** 
 * Insert primary material into materials & get id value for FK
 */
const materialPrimaryKeyArray = await knex('materials')
  .returning('id')
  .insert(materialRecord)
  .catch(error => console.error(`Unable to persist record, ${error}`)) 
const materialPrimaryKey = materialPrimaryKeyArray[0];

/**
 * Persist properties and/or notes if they exist
 */
if (material.materialProperties) {
  material.materialProperties.forEach(property => {
    property['material_id'] = materialPrimaryKey
  });
  knex('material_properties')
    .returning('id')
    .insert(material.materialProperties)
    .catch(error => console.error(`Unable to persist record, ${error}`)) 
};

if (material.materialNotes) {
  material.materialNotes.forEach(note => {
    note['material_id'] = materialPrimaryKey
  });
  knex('material_notes')
    .returning('id')
    .insert(material.materialNotes)
    .catch(error => console.error(`Unable to persist record, ${error}`)) 
   };
   
return materialPrimaryKey;

这是不起作用的:

try {
  const materialRecord = {
    name: material.name,
    description: material.description ? material.description : null,
    user_id: userId
  }

  await knex.transaction(async trx => {
    const materialPrimaryKeyArray = await knex('materials')
      .insert(materialRecord, 'id')
      .transacting(trx)
    const materialPrimaryKey = materialPrimaryKeyArray[0];

    if (material.materialProperties && material.materialProperties.length > 0) {
      material.materialProperties.forEach(property => {
        property['material_id'] = materialPrimaryKey
      })

      const propertyInserts = await knex('material_properties')
        .insert(material.materialProperties, 'id')
        .transacting(trx)
      console.log(material_properties.length + ' properties attempted to save - ' + propertyInserts.length + ' properties successfully saved.')
    };

    if (material.materialNotes && material.materialNotes.length > 0) {
      material.materialNotes.forEach(note => {
        note['material_id'] = materialPrimaryKey
      })

      const noteInserts = await knex('material_notes')
        .insert(material.materialNotes, 'id')
        .transacting(trx)
      console.log(material_notes.length + ' properties attempted to save - ' + noteInserts.length + ' notes successfully saved.')
    };

    console.log('The material is successfully saved.')
  })

  return materialPrimaryKey;
} catch (error) {
  console.error(`Unable to persist data, ${error}`)
  trx.rollback
}

table 名称相同,如您在 "propertyInserts" 的赋值中所见。

我尝试通过在插入和交易方法之间添加 .catch 来承诺每个插入:

            const materialPrimaryKeyArray = await knex('materials')
                .insert(materialRecord, 'id')
                .catch(error => `Cannot persist record, ${error}`)
                .transacting(trx)
            const materialPrimaryKey = materialPrimaryKeyArray[0];

。当我这样做时,table (material_properties) 的 ReferenceError 消失了,取而代之的是

TypeError: (0 , _connection.default)(...).insert(...).catch(...).transacting is not a function

我还尝试将 catch 语句移到事务处理语句下方。这并没有给出上面的 TypeError,但它也没有像我认为的那样修复 UnhandledPromiseRejectionWarning。

注意:我实际上是为了处理第一种类型的 async/await 事务而得到的。但是我还是不知道为什么交易方式不行。

您正在尝试访问其范围之外的 trx 变量。

} catch (error) {
  console.error(`Unable to persist data, ${error}`)
  trx.rollback // here you are trying to use undefined variable
}

您可以删除该行。由于 knex.transaction(async trx => {}) 抛出错误,事务自动回滚(因为处理函数正在重新承诺)。

同样只是访问函数而不调用它不会有任何区别 trx.rollbacktrx.rollback() 不会做同样的事情。