transaction.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. "use strict";
  2. var __defProp = Object.defineProperty;
  3. var __getOwnPropSymbols = Object.getOwnPropertySymbols;
  4. var __hasOwnProp = Object.prototype.hasOwnProperty;
  5. var __propIsEnum = Object.prototype.propertyIsEnumerable;
  6. var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  7. var __spreadValues = (a, b) => {
  8. for (var prop in b || (b = {}))
  9. if (__hasOwnProp.call(b, prop))
  10. __defNormalProp(a, prop, b[prop]);
  11. if (__getOwnPropSymbols)
  12. for (var prop of __getOwnPropSymbols(b)) {
  13. if (__propIsEnum.call(b, prop))
  14. __defNormalProp(a, prop, b[prop]);
  15. }
  16. return a;
  17. };
  18. class Transaction {
  19. constructor(sequelize, options) {
  20. this.sequelize = sequelize;
  21. this.savepoints = [];
  22. this._afterCommitHooks = [];
  23. const generateTransactionId = this.sequelize.dialect.queryGenerator.generateTransactionId;
  24. this.options = __spreadValues({
  25. type: sequelize.options.transactionType,
  26. isolationLevel: sequelize.options.isolationLevel,
  27. readOnly: false
  28. }, options);
  29. this.parent = this.options.transaction;
  30. if (this.parent) {
  31. this.id = this.parent.id;
  32. this.parent.savepoints.push(this);
  33. this.name = `${this.id}-sp-${this.parent.savepoints.length}`;
  34. } else {
  35. this.id = this.name = generateTransactionId();
  36. }
  37. delete this.options.transaction;
  38. }
  39. async commit() {
  40. if (this.finished) {
  41. throw new Error(`Transaction cannot be committed because it has been finished with state: ${this.finished}`);
  42. }
  43. try {
  44. return await this.sequelize.getQueryInterface().commitTransaction(this, this.options);
  45. } finally {
  46. this.finished = "commit";
  47. this.cleanup();
  48. for (const hook of this._afterCommitHooks) {
  49. await hook.apply(this, [this]);
  50. }
  51. }
  52. }
  53. async rollback() {
  54. if (this.finished) {
  55. throw new Error(`Transaction cannot be rolled back because it has been finished with state: ${this.finished}`);
  56. }
  57. if (!this.connection) {
  58. throw new Error("Transaction cannot be rolled back because it never started");
  59. }
  60. try {
  61. return await this.sequelize.getQueryInterface().rollbackTransaction(this, this.options);
  62. } finally {
  63. this.cleanup();
  64. }
  65. }
  66. async prepareEnvironment(useCLS) {
  67. let connectionPromise;
  68. if (useCLS === void 0) {
  69. useCLS = true;
  70. }
  71. if (this.parent) {
  72. connectionPromise = Promise.resolve(this.parent.connection);
  73. } else {
  74. const acquireOptions = { uuid: this.id };
  75. if (this.options.readOnly) {
  76. acquireOptions.type = "SELECT";
  77. }
  78. connectionPromise = this.sequelize.connectionManager.getConnection(acquireOptions);
  79. }
  80. let result;
  81. const connection = await connectionPromise;
  82. this.connection = connection;
  83. this.connection.uuid = this.id;
  84. try {
  85. await this.begin();
  86. result = await this.setDeferrable();
  87. } catch (setupErr) {
  88. try {
  89. result = await this.rollback();
  90. } finally {
  91. throw setupErr;
  92. }
  93. }
  94. if (useCLS && this.sequelize.constructor._cls) {
  95. this.sequelize.constructor._cls.set("transaction", this);
  96. }
  97. return result;
  98. }
  99. async setDeferrable() {
  100. if (this.options.deferrable) {
  101. return await this.sequelize.getQueryInterface().deferConstraints(this, this.options);
  102. }
  103. }
  104. async begin() {
  105. const queryInterface = this.sequelize.getQueryInterface();
  106. if (this.sequelize.dialect.supports.settingIsolationLevelDuringTransaction) {
  107. await queryInterface.startTransaction(this, this.options);
  108. return queryInterface.setIsolationLevel(this, this.options.isolationLevel, this.options);
  109. }
  110. await queryInterface.setIsolationLevel(this, this.options.isolationLevel, this.options);
  111. return queryInterface.startTransaction(this, this.options);
  112. }
  113. cleanup() {
  114. if (this.parent || this.connection.uuid === void 0)
  115. return;
  116. this._clearCls();
  117. const res = this.sequelize.connectionManager.releaseConnection(this.connection);
  118. this.connection.uuid = void 0;
  119. return res;
  120. }
  121. _clearCls() {
  122. const cls = this.sequelize.constructor._cls;
  123. if (cls) {
  124. if (cls.get("transaction") === this) {
  125. cls.set("transaction", null);
  126. }
  127. }
  128. }
  129. afterCommit(fn) {
  130. if (!fn || typeof fn !== "function") {
  131. throw new Error('"fn" must be a function');
  132. }
  133. this._afterCommitHooks.push(fn);
  134. }
  135. static get TYPES() {
  136. return {
  137. DEFERRED: "DEFERRED",
  138. IMMEDIATE: "IMMEDIATE",
  139. EXCLUSIVE: "EXCLUSIVE"
  140. };
  141. }
  142. static get ISOLATION_LEVELS() {
  143. return {
  144. READ_UNCOMMITTED: "READ UNCOMMITTED",
  145. READ_COMMITTED: "READ COMMITTED",
  146. REPEATABLE_READ: "REPEATABLE READ",
  147. SERIALIZABLE: "SERIALIZABLE"
  148. };
  149. }
  150. static get LOCK() {
  151. return {
  152. UPDATE: "UPDATE",
  153. SHARE: "SHARE",
  154. KEY_SHARE: "KEY SHARE",
  155. NO_KEY_UPDATE: "NO KEY UPDATE"
  156. };
  157. }
  158. get LOCK() {
  159. return Transaction.LOCK;
  160. }
  161. }
  162. module.exports = Transaction;
  163. module.exports.Transaction = Transaction;
  164. module.exports.default = Transaction;
  165. //# sourceMappingURL=transaction.js.map