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