zoukankan      html  css  js  c++  java
  • mongoose事务-transactions

    参考文档:https://www.npmjs.com/package/mongoose-transactions

    Transactions:

    事务是一组连续的数据库操作,它的执行方式就像是一个单独的工作单元。换句话说,除非组中的每个单独操作都成功,否则事务永远不会完成。如果事务中的任何操作失败,则整个事务都将失败。

    你可以把许多Mongodb查询集中到一个组中,并将它们作为事务的一部分一起执行。

    安装

    $ npm i mongoose-transactions

    安装并保存配置

    $ npm i -S mongoose-transactions

    API

    创建新实例

    const Transaction = require("mongoose-transactions");
     
    const transaction = new Transaction();

    添加一个操作

    / * *
    *创建插入事务和回滚状态。
    * @param modelName—包含mongoose模型名称的字符串。
    * @param data -包含要插入到mongoose模型的数据的对象。
    * @returns id -要插入的对象的id。
    * /
    const id =事务。插入(“modelName”,对象);
    / * *
    *创建findOneAndUpdate事务和回滚状态。
    * @param modelName—包含mogoose模型名称的字符串。
    * @param findId—要更新的对象的id。
    * @param dataObj -包含要更新到mongoose模型的数据的对象。
    * @param options -更新操作选项对象为{new: true}
    * /
    事务。更新(“modelName”,id,对象,选项);
    / * *
    *创建删除事务和回滚状态。
    * @param modelName—包含mongoose模型名称的字符串。
    * @param findObj -包含查找mongoose集合的数据的对象。
    * /
    事务。删除(“modelName”、身份证);

    运行操作

    / * *
    *如果发生任何错误,回滚执行的操作。
    * @param         stepNumber -(可选)要回滚的操作数-默认为length of
    *                         操作成功运行
    * @returns           对象数组——通过回滚操作返回的对象
    *                         Error -错误对象包含:
    *                         data -操作的输入数据
    *                         error -操作返回的错误
    *                         executedTransactions——回滚操作的数量
    *                         保留事务——未回滚操作的数量
    * /
    transaction.rollback ();/ /返回承诺                                

    清除

    / * *
    清除transactions对象,以便在同一个实例上开始一个新的事务。
    * /
    
    transaction.clean ();//清除以前的操作

    举例

    Full example:
    
    const Transaction = require("mongoose-transactions");
    const transaction = new Transaction();
     
    const person = "Person"; // 注册模式名称
     
    const jonathanObject = {
      age: 18,
      name: "Jonathan"
    };
    const aliceObject = {
      age: 23,
      name: "Alice"
    };
     
    async function start() {
      try {
        const jonathanId = transaction.insert(person, jonathanObject);
        transaction.update(person, jonathanId, aliceObject);
        transaction.remove(person, "fakeId"); // 这个操作失败了
        const final = await transaction.run();
        // 希望(final[0].name).toBe('Jonathan')
      } catch (error) {
        console.error(error);
        const rollbackObj = await transaction.rollback().catch(console.error);
        transaction.clean();
        //  expect(rollbacks[0].name).toBe('Alice')
        //  expect(rollbacks[0].age).toBe(aliceObject.age)
        //  expect(rollbacks[1].name).toBe('Jonathan')
        //  expect(rollbacks[1].age).toBe(bobObject.age)
      }
    }
     
    start();

    操作对象

    你可以调用getOperations方法获取操作对象

    /**
     * Get transaction operations array from transaction object or collection on db.
     * @param transactionId - Optional. If the transaction id is passed return the elements of the transaction id
     *                                  else return the elements of current transaction (default null).
     */
    const operations = transaction.getOperations();

    为了调试目的,你可以检查事务对操作对象的数组设计:

    // console.log(operations)
    [
      {
        /** 要运行的事务类型 */
        type: string, // 'insert', 'update', 'remove'
        /** 要执行回滚的事务类型 */
        rollbackType: string, // 'remove', 'update', 'insert'
        /** mongoose模型实例 */
        model: any, // compiled mongoose model
        /** mongoose模型名称 */
        modelName: string, // 'Person'
        /** 如歌存在事务处理前的mongoose模型实例*/
        oldModel: any, // model used for rollback
        /** 对象的Id */
        findId: any,
        /** 数据 */
        data: any,
        /** 选项配置查询 */
        options: any,
        /** 操作当前状态 */
        status: Status
      }
    ];
     
    /** 操作可能的状态为: */
    Status = ["Pending", "Success", "Error", "Rollback", "ErrorRollback"];

    提示:状态会自动更新,因此你可以在需要时检查事务的操作的当前状态。

    创建具有存储和把事务加载到表单上的事务实例

    const useDB = true;
    const transaction = new Transaction(useDB);

    首先你要获取一个实际的事务ID,你可以用这个id在数据库中加载事务对象。

    /**
     * If the instance is db true, return the actual or new transaction id.
     * @throws Error - Throws error if the instance is not a db instance.
     */
    const transId = await transaction.getTransactionId();

    你可以调用loadDBTransaction函数在数据库中加载一个事务对象。

    /**
     * Load transaction from transaction collection on db.
     * @param transactionId - The id of the transaction to load.
     * @trows Error - Throws error if the transaction is not found
     */
    await transaction.loadDbTransaction(transId);

    你可以调用saveOperations方法在数据库中保存操作对象

    /**
     * Save transaction operations array on db.
     * @throws Error - Throws error if the instance is not a db instance.
     * @return transactionId - The transaction id on database
     */
    const transId = await transaction.saveOperations();

    完整的例子:

    const Transaction = require("mongoose-transactions");
    const useDB = true;
    const transaction = new Transaction(useDB);
     
    const person: string = "Person";
     
    const tonyObject: any = {
      age: 28,
      name: "Tony"
    };
     
    const nicolaObject: any = {
      age: 32,
      name: "Nicola"
    };
     
    async function start() {
      // 在事务实例上创建操作
      const id = transaction.insert(person, tonyObject);
      transaction.update(person, id, nicolaObject, { new: true });
     
      // 获取和保存创建的操作,saveOperations方法返回保存在数据库上的事务id
      const operations = transaction.getOperations();
      const transId = await transaction.saveOperations();
     
      // 创建一个新的事务实例
      const newTransaction = new Transaction(true);
     
      // 使用transId在新事务实例中加载保存的操作
      await newTransaction.loadDbTransaction(transId);
     
      // 如果需要,可以获取操作对象
      const newOperations = newTransaction.getOperations();
     
      // 最后运行并回滚 
      try {
        const final = await newTransaction.run();
      } catch (err) {
        const rolled = await newTransaction.rollback();
      }
    }
     
    start();
  • 相关阅读:
    POJ 2503 Babelfish
    POJ 2528 Mayor's posters
    203C Photographer
    190A Vasya and the Bus
    POJ 3630 Trie树 TLE
    ThinkPHP验证码的使用
    mysql_fetch_row、mysql_fetch_array、mysql_fetch_assoc、mysql_fetch_object
    ThinkPHP模版布局方式
    Windows 下使用Git管理Github项目
    浅析mysql、mysqli、PDO
  • 原文地址:https://www.cnblogs.com/dlsj-cn/p/12886869.html
Copyright © 2011-2022 走看看