index.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const index_1 = require("../index");
  4. const collection_1 = require("../collection");
  5. const code_1 = require("../const/code");
  6. const START = 'database.startTransaction';
  7. const COMMIT = 'database.commitTransaction';
  8. const ABORT = 'database.abortTransaction';
  9. class Transaction {
  10. constructor(db) {
  11. this._db = db;
  12. this._request = new index_1.Db.reqClass(this._db.config);
  13. this.aborted = false;
  14. this.commited = false;
  15. this.inited = false;
  16. }
  17. async init() {
  18. const res = await this._request.send(START);
  19. if (res.code) {
  20. throw res;
  21. }
  22. this.inited = true;
  23. this._id = res.transactionId;
  24. }
  25. collection(collName) {
  26. if (!collName) {
  27. throw new Error('Collection name is required');
  28. }
  29. return new collection_1.CollectionReference(this._db, collName, {}, this._id);
  30. }
  31. getTransactionId() {
  32. return this._id;
  33. }
  34. getRequestMethod() {
  35. return this._request;
  36. }
  37. async commit() {
  38. const param = {
  39. transactionId: this._id
  40. };
  41. const res = await this._request.send(COMMIT, param);
  42. if (res.code)
  43. throw res;
  44. this.commited = true;
  45. return res;
  46. }
  47. async rollback(customRollbackRes) {
  48. const param = {
  49. transactionId: this._id
  50. };
  51. const res = await this._request.send(ABORT, param);
  52. if (res.code)
  53. throw res;
  54. this.aborted = true;
  55. this.abortReason = customRollbackRes;
  56. return res;
  57. }
  58. }
  59. exports.Transaction = Transaction;
  60. async function startTransaction() {
  61. const transaction = new Transaction(this);
  62. await transaction.init();
  63. return transaction;
  64. }
  65. exports.startTransaction = startTransaction;
  66. async function runTransaction(callback, times = 3) {
  67. let transaction;
  68. try {
  69. transaction = new Transaction(this);
  70. await transaction.init();
  71. const callbackRes = await callback(transaction);
  72. if (transaction.aborted === true) {
  73. throw transaction.abortReason;
  74. }
  75. await transaction.commit();
  76. return callbackRes;
  77. }
  78. catch (error) {
  79. if (transaction.inited === false) {
  80. throw error;
  81. }
  82. const throwWithRollback = async (error) => {
  83. if (!transaction.aborted && !transaction.commited) {
  84. try {
  85. await transaction.rollback();
  86. }
  87. catch (err) {
  88. }
  89. throw error;
  90. }
  91. if (transaction.aborted === true) {
  92. throw transaction.abortReason;
  93. }
  94. throw error;
  95. };
  96. if (times <= 0) {
  97. await throwWithRollback(error);
  98. }
  99. if (error && error.code === code_1.ERRORS.DATABASE_TRANSACTION_CONFLICT.code) {
  100. return await runTransaction.bind(this)(callback, --times);
  101. }
  102. await throwWithRollback(error);
  103. }
  104. }
  105. exports.runTransaction = runTransaction;