transaction.js 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. 'use strict'
  2. const debug = require('debug')('mssql:tedi')
  3. const BaseTransaction = require('../base/transaction')
  4. const { IDS } = require('../utils')
  5. const TransactionError = require('../error/transaction-error')
  6. class Transaction extends BaseTransaction {
  7. constructor (parent) {
  8. super(parent)
  9. this._abort = () => {
  10. if (!this._rollbackRequested) {
  11. // transaction interrupted because of XACT_ABORT
  12. const pc = this._acquiredConnection
  13. // defer releasing so connection can switch from SentClientRequest to LoggedIn state
  14. setImmediate(this.parent.release.bind(this.parent), pc)
  15. this._acquiredConnection.removeListener('rollbackTransaction', this._abort)
  16. this._acquiredConnection = null
  17. this._acquiredConfig = null
  18. this._aborted = true
  19. this.emit('rollback', true)
  20. }
  21. }
  22. }
  23. _begin (isolationLevel, callback) {
  24. super._begin(isolationLevel, err => {
  25. if (err) return callback(err)
  26. debug('transaction(%d): begin', IDS.get(this))
  27. this.parent.acquire(this, (err, connection, config) => {
  28. if (err) return callback(err)
  29. this._acquiredConnection = connection
  30. this._acquiredConnection.on('rollbackTransaction', this._abort)
  31. this._acquiredConfig = config
  32. connection.beginTransaction(err => {
  33. if (err) err = new TransactionError(err)
  34. debug('transaction(%d): begun', IDS.get(this))
  35. callback(err)
  36. }, this.name, this.isolationLevel)
  37. })
  38. })
  39. }
  40. _commit (callback) {
  41. super._commit(err => {
  42. if (err) return callback(err)
  43. debug('transaction(%d): commit', IDS.get(this))
  44. this._acquiredConnection.commitTransaction(err => {
  45. if (err) err = new TransactionError(err)
  46. this._acquiredConnection.removeListener('rollbackTransaction', this._abort)
  47. this.parent.release(this._acquiredConnection)
  48. this._acquiredConnection = null
  49. this._acquiredConfig = null
  50. if (!err) debug('transaction(%d): commited', IDS.get(this))
  51. callback(err)
  52. })
  53. })
  54. }
  55. _rollback (callback) {
  56. super._rollback(err => {
  57. if (err) return callback(err)
  58. debug('transaction(%d): rollback', IDS.get(this))
  59. this._acquiredConnection.rollbackTransaction(err => {
  60. if (err) err = new TransactionError(err)
  61. this._acquiredConnection.removeListener('rollbackTransaction', this._abort)
  62. this.parent.release(this._acquiredConnection)
  63. this._acquiredConnection = null
  64. this._acquiredConfig = null
  65. if (!err) debug('transaction(%d): rolled back', IDS.get(this))
  66. callback(err)
  67. })
  68. })
  69. }
  70. }
  71. module.exports = Transaction