wangzhibo
2026-05-09 53418655c061ac26f66058253f39200aced1ab1d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
'use strict'
 
const debug = require('debug')('mssql:msv8')
const BaseTransaction = require('../base/transaction')
const { IDS } = require('../utils')
const Request = require('./request')
const ISOLATION_LEVEL = require('../isolationlevel')
const TransactionError = require('../error/transaction-error')
 
const isolationLevelDeclaration = function (type) {
  switch (type) {
    case ISOLATION_LEVEL.READ_UNCOMMITTED: return 'READ UNCOMMITTED'
    case ISOLATION_LEVEL.READ_COMMITTED: return 'READ COMMITTED'
    case ISOLATION_LEVEL.REPEATABLE_READ: return 'REPEATABLE READ'
    case ISOLATION_LEVEL.SERIALIZABLE: return 'SERIALIZABLE'
    case ISOLATION_LEVEL.SNAPSHOT: return 'SNAPSHOT'
    default: throw new TransactionError('Invalid isolation level.')
  }
}
 
class Transaction extends BaseTransaction {
  _begin (isolationLevel, callback) {
    super._begin(isolationLevel, err => {
      if (err) return callback(err)
 
      debug('transaction(%d): begin', IDS.get(this))
 
      this.parent.acquire(this, (err, connection, config) => {
        if (err) return callback(err)
 
        this._acquiredConnection = connection
        this._acquiredConfig = config
 
        const req = new Request(this)
        req.stream = false
        req.query(`set transaction isolation level ${isolationLevelDeclaration(this.isolationLevel)};begin tran;`, err => {
          if (err) {
            this.parent.release(this._acquiredConnection)
            this._acquiredConnection = null
            this._acquiredConfig = null
 
            return callback(err)
          }
 
          debug('transaction(%d): begun', IDS.get(this))
 
          callback(null)
        })
      })
    })
  }
 
  _commit (callback) {
    super._commit(err => {
      if (err) return callback(err)
 
      debug('transaction(%d): commit', IDS.get(this))
 
      const req = new Request(this)
      req.stream = false
      req.query('commit tran', err => {
        if (err) err = new TransactionError(err)
 
        this.parent.release(this._acquiredConnection)
        this._acquiredConnection = null
        this._acquiredConfig = null
 
        if (!err) debug('transaction(%d): commited', IDS.get(this))
 
        callback(null)
      })
    })
  }
 
  _rollback (callback) {
    super._commit(err => {
      if (err) return callback(err)
 
      debug('transaction(%d): rollback', IDS.get(this))
 
      const req = new Request(this)
      req.stream = false
      req.query('rollback tran', err => {
        if (err) err = new TransactionError(err)
 
        this.parent.release(this._acquiredConnection)
        this._acquiredConnection = null
        this._acquiredConfig = null
 
        if (!err) debug('transaction(%d): rolled back', IDS.get(this))
 
        callback(null)
      })
    })
  }
}
 
module.exports = Transaction