@nest-omni/core 4.1.3-14 → 4.1.3-17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/audit/audit.module.js +7 -0
- package/audit/services/entity-audit.service.js +2 -1
- package/audit/services/manual-audit-log.service.js +2 -2
- package/audit/services/multi-database.service.d.ts +0 -5
- package/audit/services/multi-database.service.js +0 -24
- package/audit/services/transaction-audit.service.js +3 -2
- package/cache/dependencies/db.dependency.d.ts +2 -2
- package/cache/dependencies/db.dependency.js +4 -4
- package/decorators/field.decorators.d.ts +1 -1
- package/http-client/examples/proxy-from-environment.example.d.ts +1 -1
- package/http-client/examples/proxy-from-environment.example.js +18 -19
- package/http-client/services/logging.service.js +2 -3
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/package.json +3 -2
- package/setup/bootstrap.setup.d.ts +1 -1
- package/shared/service-registry.module.js +2 -15
- package/shared/services/api-config.service.js +1 -0
- package/validators/is-exists.validator.d.ts +2 -7
- package/validators/is-exists.validator.js +2 -24
- package/validators/is-unique.validator.d.ts +2 -7
- package/validators/is-unique.validator.js +2 -24
- package/transaction/__tests__/mocks.d.ts +0 -9
- package/transaction/__tests__/mocks.js +0 -33
- package/transaction/base-service-transaction.d.ts +0 -99
- package/transaction/base-service-transaction.js +0 -286
- package/transaction/cls-compatibility.service.d.ts +0 -55
- package/transaction/cls-compatibility.service.js +0 -127
- package/transaction/data-source-registry.d.ts +0 -91
- package/transaction/data-source-registry.js +0 -349
- package/transaction/data-source.util.d.ts +0 -142
- package/transaction/data-source.util.js +0 -330
- package/transaction/database-adapter.d.ts +0 -44
- package/transaction/database-adapter.js +0 -240
- package/transaction/decorators/entity-datasource.decorator.d.ts +0 -62
- package/transaction/decorators/entity-datasource.decorator.js +0 -105
- package/transaction/index.d.ts +0 -15
- package/transaction/index.js +0 -68
- package/transaction/logging-transactional.interceptor.d.ts +0 -18
- package/transaction/logging-transactional.interceptor.js +0 -163
- package/transaction/transaction-context.service.d.ts +0 -137
- package/transaction/transaction-context.service.js +0 -411
- package/transaction/transaction-manager.d.ts +0 -230
- package/transaction/transaction-manager.js +0 -1001
- package/transaction/transaction-synchronization.d.ts +0 -171
- package/transaction/transaction-synchronization.js +0 -380
- package/transaction/transaction.errors.d.ts +0 -91
- package/transaction/transaction.errors.js +0 -206
- package/transaction/transaction.module.d.ts +0 -30
- package/transaction/transaction.module.js +0 -98
- package/transaction/transactional.decorator.d.ts +0 -82
- package/transaction/transactional.decorator.js +0 -319
- package/transaction/typeorm-module-wrapper.d.ts +0 -96
- package/transaction/typeorm-module-wrapper.js +0 -197
|
@@ -1,411 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
-
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
-
};
|
|
14
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
15
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
16
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
17
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
18
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
19
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
20
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
21
|
-
});
|
|
22
|
-
};
|
|
23
|
-
var TransactionContextService_1;
|
|
24
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.TransactionContextService = void 0;
|
|
26
|
-
const common_1 = require("@nestjs/common");
|
|
27
|
-
const core_1 = require("@nestjs/core");
|
|
28
|
-
const typeorm_1 = require("@nestjs/typeorm");
|
|
29
|
-
const async_hooks_1 = require("async_hooks");
|
|
30
|
-
/**
|
|
31
|
-
* 全局数据源注册表
|
|
32
|
-
* 在模块初始化时设置,跨请求共享
|
|
33
|
-
*/
|
|
34
|
-
class GlobalDataSourceRegistry {
|
|
35
|
-
static setConfig(config) {
|
|
36
|
-
GlobalDataSourceRegistry.config = config;
|
|
37
|
-
}
|
|
38
|
-
static getConfig() {
|
|
39
|
-
return GlobalDataSourceRegistry.config;
|
|
40
|
-
}
|
|
41
|
-
static addDataSource(name, config) {
|
|
42
|
-
GlobalDataSourceRegistry.dataSources.set(name, config);
|
|
43
|
-
}
|
|
44
|
-
static removeDataSource(name) {
|
|
45
|
-
GlobalDataSourceRegistry.dataSources.delete(name);
|
|
46
|
-
}
|
|
47
|
-
static getDataSource(name) {
|
|
48
|
-
return GlobalDataSourceRegistry.dataSources.get(name);
|
|
49
|
-
}
|
|
50
|
-
static getAllDataSources() {
|
|
51
|
-
return Array.from(GlobalDataSourceRegistry.dataSources.keys());
|
|
52
|
-
}
|
|
53
|
-
static hasDataSource(name) {
|
|
54
|
-
return GlobalDataSourceRegistry.dataSources.has(name);
|
|
55
|
-
}
|
|
56
|
-
static clear() {
|
|
57
|
-
GlobalDataSourceRegistry.dataSources.clear();
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
GlobalDataSourceRegistry.dataSources = new Map();
|
|
61
|
-
GlobalDataSourceRegistry.config = {};
|
|
62
|
-
/**
|
|
63
|
-
* AsyncLocalStorage 实例
|
|
64
|
-
* 用于在每个请求上下文中存储 TransactionContextService
|
|
65
|
-
*/
|
|
66
|
-
const asyncLocalStorage = new async_hooks_1.AsyncLocalStorage();
|
|
67
|
-
/**
|
|
68
|
-
* 事务上下文管理器
|
|
69
|
-
* 使用 RequestScope 确保每个请求都有独立的事务上下文
|
|
70
|
-
*/
|
|
71
|
-
let TransactionContextService = TransactionContextService_1 = class TransactionContextService {
|
|
72
|
-
constructor(moduleRef, config) {
|
|
73
|
-
this.moduleRef = moduleRef;
|
|
74
|
-
this.config = config;
|
|
75
|
-
this.contextMap = new Map();
|
|
76
|
-
}
|
|
77
|
-
onModuleInit() {
|
|
78
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
-
// 将配置存储到全局注册表
|
|
80
|
-
GlobalDataSourceRegistry.setConfig(this.config);
|
|
81
|
-
// 将当前实例存储到 AsyncLocalStorage
|
|
82
|
-
asyncLocalStorage.enterWith(this);
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* 获取当前请求的事务上下文服务
|
|
87
|
-
*/
|
|
88
|
-
static getCurrent() {
|
|
89
|
-
return asyncLocalStorage.getStore();
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* 获取当前请求的数据源
|
|
93
|
-
* 方便其他模块快速访问数据源
|
|
94
|
-
* @param dataSourceName 数据源名称,默认为 'default'
|
|
95
|
-
* @returns DataSource 实例
|
|
96
|
-
*/
|
|
97
|
-
static getDataSource(dataSourceName = 'default') {
|
|
98
|
-
const currentService = this.getCurrent();
|
|
99
|
-
if (currentService) {
|
|
100
|
-
// 从当前服务获取数据源
|
|
101
|
-
const dataSource = currentService.getDataSource(dataSourceName);
|
|
102
|
-
if (dataSource) {
|
|
103
|
-
return dataSource;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
// 如果当前服务中没有,尝试从全局注册表获取
|
|
107
|
-
const globalDataSource = GlobalDataSourceRegistry.getDataSource(dataSourceName);
|
|
108
|
-
if (globalDataSource) {
|
|
109
|
-
return globalDataSource.dataSource;
|
|
110
|
-
}
|
|
111
|
-
throw new Error(`DataSource '${dataSourceName}' not found. Please ensure it is registered ` +
|
|
112
|
-
`either through TypeOrmModule or addDataSource(), and that the method is ` +
|
|
113
|
-
`called within a request context.`);
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* 设置事务上下文
|
|
117
|
-
*/
|
|
118
|
-
setContext(dataSourceName, entityManager) {
|
|
119
|
-
const dataSource = this.moduleRef.get((0, typeorm_1.getDataSourceToken)(dataSourceName), {
|
|
120
|
-
strict: false,
|
|
121
|
-
});
|
|
122
|
-
this.contextMap.set(dataSourceName, {
|
|
123
|
-
dataSourceName,
|
|
124
|
-
entityManager,
|
|
125
|
-
dataSource,
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* 获取事务上下文中的 EntityManager
|
|
130
|
-
*/
|
|
131
|
-
getEntityManager(dataSourceName = 'default') {
|
|
132
|
-
const context = this.contextMap.get(dataSourceName);
|
|
133
|
-
return (context === null || context === void 0 ? void 0 : context.entityManager) || null;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* 获取事务上下文中的 DataSource
|
|
137
|
-
* 如果上下文中没有,则尝试从 TypeORM 模块或全局注册表获取
|
|
138
|
-
*/
|
|
139
|
-
getDataSource(dataSourceName = 'default') {
|
|
140
|
-
// 1. 首先检查事务上下文
|
|
141
|
-
const context = this.contextMap.get(dataSourceName);
|
|
142
|
-
if (context === null || context === void 0 ? void 0 : context.dataSource) {
|
|
143
|
-
return context.dataSource;
|
|
144
|
-
}
|
|
145
|
-
// 2. 检查全局注册表中的动态数据源
|
|
146
|
-
const dynamicDataSource = GlobalDataSourceRegistry.getDataSource(dataSourceName);
|
|
147
|
-
if (dynamicDataSource) {
|
|
148
|
-
return dynamicDataSource.dataSource;
|
|
149
|
-
}
|
|
150
|
-
// 3. 尝试从 TypeORM 模块获取
|
|
151
|
-
try {
|
|
152
|
-
const dataSource = this.moduleRef.get((0, typeorm_1.getDataSourceToken)(dataSourceName), {
|
|
153
|
-
strict: false,
|
|
154
|
-
});
|
|
155
|
-
if (dataSource) {
|
|
156
|
-
return dataSource;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
catch (error) {
|
|
160
|
-
// 忽略未找到数据源的错误
|
|
161
|
-
}
|
|
162
|
-
return null;
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* 检查是否在事务中
|
|
166
|
-
*/
|
|
167
|
-
isInTransaction(dataSourceName = 'default') {
|
|
168
|
-
var _a, _b;
|
|
169
|
-
const context = this.contextMap.get(dataSourceName);
|
|
170
|
-
return ((_b = (_a = context === null || context === void 0 ? void 0 : context.entityManager) === null || _a === void 0 ? void 0 : _a.queryRunner) === null || _b === void 0 ? void 0 : _b.isTransactionActive) || false;
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* 获取所有活跃的事务上下文
|
|
174
|
-
*/
|
|
175
|
-
getAllActiveContexts() {
|
|
176
|
-
var _a, _b;
|
|
177
|
-
const activeContexts = new Map();
|
|
178
|
-
for (const [name, context] of this.contextMap) {
|
|
179
|
-
if ((_b = (_a = context.entityManager) === null || _a === void 0 ? void 0 : _a.queryRunner) === null || _b === void 0 ? void 0 : _b.isTransactionActive) {
|
|
180
|
-
activeContexts.set(name, context);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
return activeContexts;
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* 清理所有事务上下文
|
|
187
|
-
*/
|
|
188
|
-
clearContext() {
|
|
189
|
-
this.contextMap.clear();
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* 清理指定数据源的事务上下文
|
|
193
|
-
*/
|
|
194
|
-
clearContextForDataSource(dataSourceName) {
|
|
195
|
-
this.contextMap.delete(dataSourceName);
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* 执行带事务的操作
|
|
199
|
-
* 如果已在事务中,使用现有的事务管理器
|
|
200
|
-
* 否则创建新事务
|
|
201
|
-
*/
|
|
202
|
-
executeInTransaction(dataSourceName, operation, isolationLevel) {
|
|
203
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
204
|
-
var _a;
|
|
205
|
-
const existingEntityManager = this.getEntityManager(dataSourceName);
|
|
206
|
-
if (existingEntityManager && ((_a = existingEntityManager.queryRunner) === null || _a === void 0 ? void 0 : _a.isTransactionActive)) {
|
|
207
|
-
// 已在事务中,直接使用现有的 EntityManager
|
|
208
|
-
return operation(existingEntityManager);
|
|
209
|
-
}
|
|
210
|
-
// 不在事务中,创建新事务
|
|
211
|
-
const dataSource = yield this.getDataSourceInstance(dataSourceName);
|
|
212
|
-
return yield dataSource.transaction((entityManager) => __awaiter(this, void 0, void 0, function* () {
|
|
213
|
-
this.setContext(dataSourceName, entityManager);
|
|
214
|
-
try {
|
|
215
|
-
const result = yield operation(entityManager);
|
|
216
|
-
return result;
|
|
217
|
-
}
|
|
218
|
-
finally {
|
|
219
|
-
this.clearContextForDataSource(dataSourceName);
|
|
220
|
-
}
|
|
221
|
-
}));
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* 获取 DataSource 实例
|
|
226
|
-
*/
|
|
227
|
-
getDataSourceInstance(dataSourceName) {
|
|
228
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
229
|
-
// 首先检查全局注册表中的动态数据源
|
|
230
|
-
const dynamicDataSource = GlobalDataSourceRegistry.getDataSource(dataSourceName);
|
|
231
|
-
if (dynamicDataSource) {
|
|
232
|
-
return dynamicDataSource.dataSource;
|
|
233
|
-
}
|
|
234
|
-
// 然后检查 TypeORM 模块注册的数据源
|
|
235
|
-
try {
|
|
236
|
-
const dataSource = this.moduleRef.get((0, typeorm_1.getDataSourceToken)(dataSourceName), {
|
|
237
|
-
strict: false,
|
|
238
|
-
});
|
|
239
|
-
if (dataSource) {
|
|
240
|
-
return dataSource;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
catch (error) {
|
|
244
|
-
// 忽略未找到数据源的错误,继续检查其他地方
|
|
245
|
-
}
|
|
246
|
-
throw new Error(`DataSource '${dataSourceName}' not found. Please ensure it is registered either through TypeOrmModule or addDataSource()`);
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* 动态注册数据源
|
|
251
|
-
*/
|
|
252
|
-
static addDataSource(name, dataSource, options) {
|
|
253
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
254
|
-
const config = GlobalDataSourceRegistry.getConfig();
|
|
255
|
-
// 检查是否允许动态注册
|
|
256
|
-
if ((config === null || config === void 0 ? void 0 : config.enableDynamicRegistration) === false) {
|
|
257
|
-
throw new Error('Dynamic data source registration is disabled');
|
|
258
|
-
}
|
|
259
|
-
// 检查是否已存在
|
|
260
|
-
if (GlobalDataSourceRegistry.hasDataSource(name) && !(options === null || options === void 0 ? void 0 : options.replaceExisting)) {
|
|
261
|
-
throw new Error(`DataSource '${name}' already registered. Use replaceExisting: true to replace.`);
|
|
262
|
-
}
|
|
263
|
-
// 验证数据源
|
|
264
|
-
if (!dataSource || !dataSource.isInitialized) {
|
|
265
|
-
throw new Error(`DataSource '${name}' must be initialized before registration`);
|
|
266
|
-
}
|
|
267
|
-
// 注册数据源
|
|
268
|
-
const dsConfig = {
|
|
269
|
-
name,
|
|
270
|
-
dataSource,
|
|
271
|
-
options: options === null || options === void 0 ? void 0 : options.options,
|
|
272
|
-
metadata: options === null || options === void 0 ? void 0 : options.metadata,
|
|
273
|
-
createdAt: new Date(),
|
|
274
|
-
};
|
|
275
|
-
GlobalDataSourceRegistry.addDataSource(name, dsConfig);
|
|
276
|
-
// 记录日志
|
|
277
|
-
if ((config === null || config === void 0 ? void 0 : config.logDataSourceRegistration) !== false) {
|
|
278
|
-
TransactionContextService_1.logger.log(`Registered dynamic DataSource: ${name}`);
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* 移除动态注册的数据源
|
|
284
|
-
*/
|
|
285
|
-
static removeDataSource(name) {
|
|
286
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
287
|
-
const removed = GlobalDataSourceRegistry.hasDataSource(name);
|
|
288
|
-
if (removed) {
|
|
289
|
-
GlobalDataSourceRegistry.removeDataSource(name);
|
|
290
|
-
// 清理当前请求中该数据源的事务上下文
|
|
291
|
-
const currentService = asyncLocalStorage.getStore();
|
|
292
|
-
if (currentService) {
|
|
293
|
-
currentService.clearContextForDataSource(name);
|
|
294
|
-
}
|
|
295
|
-
TransactionContextService_1.logger.log(`Removed dynamic DataSource: ${name}`);
|
|
296
|
-
}
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
/**
|
|
300
|
-
* 获取所有已注册的数据源名称
|
|
301
|
-
*/
|
|
302
|
-
static getRegisteredDataSources() {
|
|
303
|
-
return GlobalDataSourceRegistry.getAllDataSources();
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* 获取动态数据源的配置
|
|
307
|
-
*/
|
|
308
|
-
static getDataSourceConfig(name) {
|
|
309
|
-
return GlobalDataSourceRegistry.getDataSource(name);
|
|
310
|
-
}
|
|
311
|
-
/**
|
|
312
|
-
* 检查数据源是否已注册
|
|
313
|
-
*/
|
|
314
|
-
static isDataSourceRegistered(name) {
|
|
315
|
-
return GlobalDataSourceRegistry.hasDataSource(name);
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* 批量注册数据源
|
|
319
|
-
*/
|
|
320
|
-
static addDataSources(dataSources, options) {
|
|
321
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
322
|
-
const errors = [];
|
|
323
|
-
for (const ds of dataSources) {
|
|
324
|
-
try {
|
|
325
|
-
yield TransactionContextService_1.addDataSource(ds.name, ds.dataSource, {
|
|
326
|
-
options: ds.options,
|
|
327
|
-
metadata: ds.metadata,
|
|
328
|
-
replaceExisting: options === null || options === void 0 ? void 0 : options.replaceExisting,
|
|
329
|
-
});
|
|
330
|
-
}
|
|
331
|
-
catch (error) {
|
|
332
|
-
if (options === null || options === void 0 ? void 0 : options.continueOnError) {
|
|
333
|
-
errors.push(error);
|
|
334
|
-
}
|
|
335
|
-
else {
|
|
336
|
-
throw error;
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
if (errors.length > 0) {
|
|
341
|
-
throw new Error(`Failed to register some DataSources: ${errors.map(e => e.message).join(', ')}`);
|
|
342
|
-
}
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* 清理全局注册表(用于测试)
|
|
347
|
-
*/
|
|
348
|
-
static clearGlobalRegistry() {
|
|
349
|
-
GlobalDataSourceRegistry.clear();
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* 获取默认数据源名称
|
|
353
|
-
*/
|
|
354
|
-
getDefaultDataSourceName() {
|
|
355
|
-
var _a;
|
|
356
|
-
return ((_a = this.config) === null || _a === void 0 ? void 0 : _a.defaultDataSource) || 'default';
|
|
357
|
-
}
|
|
358
|
-
/**
|
|
359
|
-
* 跨多个数据源执行分布式事务
|
|
360
|
-
* 使用两阶段提交模式
|
|
361
|
-
*/
|
|
362
|
-
executeDistributedTransaction(dataSourceNames, operation) {
|
|
363
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
364
|
-
const entityManagers = new Map();
|
|
365
|
-
const dataSources = [];
|
|
366
|
-
try {
|
|
367
|
-
// 获取所有数据源
|
|
368
|
-
for (const dataSourceName of dataSourceNames) {
|
|
369
|
-
const dataSource = yield this.getDataSourceInstance(dataSourceName);
|
|
370
|
-
dataSources.push(dataSource);
|
|
371
|
-
}
|
|
372
|
-
// 开始分布式事务
|
|
373
|
-
const results = yield Promise.all(dataSources.map((dataSource) => __awaiter(this, void 0, void 0, function* () {
|
|
374
|
-
return dataSource.transaction((entityManager) => __awaiter(this, void 0, void 0, function* () {
|
|
375
|
-
const index = dataSources.indexOf(dataSource);
|
|
376
|
-
const dataSourceName = dataSourceNames[index];
|
|
377
|
-
entityManagers.set(dataSourceName, entityManager);
|
|
378
|
-
this.setContext(dataSourceName, entityManager);
|
|
379
|
-
// 第一阶段:准备
|
|
380
|
-
// 这里只是执行操作,实际的提交将在所有操作成功后进行
|
|
381
|
-
return { dataSourceName, entityManager };
|
|
382
|
-
}));
|
|
383
|
-
})));
|
|
384
|
-
// 执行业务操作
|
|
385
|
-
const result = yield operation(entityManagers);
|
|
386
|
-
return result;
|
|
387
|
-
}
|
|
388
|
-
catch (error) {
|
|
389
|
-
// 发生错误时清理上下文
|
|
390
|
-
for (const dataSourceName of dataSourceNames) {
|
|
391
|
-
this.clearContextForDataSource(dataSourceName);
|
|
392
|
-
}
|
|
393
|
-
throw error;
|
|
394
|
-
}
|
|
395
|
-
finally {
|
|
396
|
-
// 清理上下文
|
|
397
|
-
for (const dataSourceName of dataSourceNames) {
|
|
398
|
-
this.clearContextForDataSource(dataSourceName);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
};
|
|
404
|
-
exports.TransactionContextService = TransactionContextService;
|
|
405
|
-
TransactionContextService.logger = new common_1.Logger(TransactionContextService_1.name);
|
|
406
|
-
exports.TransactionContextService = TransactionContextService = TransactionContextService_1 = __decorate([
|
|
407
|
-
(0, common_1.Injectable)({ scope: common_1.Scope.REQUEST }),
|
|
408
|
-
__param(1, (0, common_1.Optional)()),
|
|
409
|
-
__param(1, (0, common_1.Inject)('TRANSACTION_CONFIG')),
|
|
410
|
-
__metadata("design:paramtypes", [core_1.ModuleRef, Object])
|
|
411
|
-
], TransactionContextService);
|
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
import { EntityManager, DataSource, QueryRunner } from 'typeorm';
|
|
2
|
-
import { TransactionContextService } from './transaction-context.service';
|
|
3
|
-
/**
|
|
4
|
-
* 事务传播行为
|
|
5
|
-
*/
|
|
6
|
-
export declare enum Propagation {
|
|
7
|
-
/**
|
|
8
|
-
* 支持当前事务,如果不存在就创建一个新事务
|
|
9
|
-
*/
|
|
10
|
-
REQUIRED = 0,
|
|
11
|
-
/**
|
|
12
|
-
* 支持当前事务,如果不存在就以非事务方式执行
|
|
13
|
-
*/
|
|
14
|
-
SUPPORTS = 1,
|
|
15
|
-
/**
|
|
16
|
-
* 支持当前事务,如果不存在就抛出异常
|
|
17
|
-
*/
|
|
18
|
-
MANDATORY = 2,
|
|
19
|
-
/**
|
|
20
|
-
* 创建新事务,如果当前存在事务就挂起它
|
|
21
|
-
*/
|
|
22
|
-
REQUIRES_NEW = 3,
|
|
23
|
-
/**
|
|
24
|
-
* 以非事务方式执行,如果当前存在事务就挂起它
|
|
25
|
-
*/
|
|
26
|
-
NOT_SUPPORTED = 4,
|
|
27
|
-
/**
|
|
28
|
-
* 以非事务方式执行,如果当前存在事务就抛出异常
|
|
29
|
-
*/
|
|
30
|
-
NEVER = 5,
|
|
31
|
-
/**
|
|
32
|
-
* 如果当前存在事务,就在嵌套事务中执行
|
|
33
|
-
*/
|
|
34
|
-
NESTED = 6
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* 事务隔离级别
|
|
38
|
-
*/
|
|
39
|
-
export declare enum IsolationLevel {
|
|
40
|
-
DEFAULT = -1,
|
|
41
|
-
READ_UNCOMMITTED = 1,
|
|
42
|
-
READ_COMMITTED = 2,
|
|
43
|
-
REPEATABLE_READ = 3,
|
|
44
|
-
SERIALIZABLE = 4
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* 事务超时处理回调
|
|
48
|
-
*/
|
|
49
|
-
export interface TransactionTimeoutCallback {
|
|
50
|
-
(status: TransactionStatus): Promise<void> | void;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* 事务定义
|
|
54
|
-
*/
|
|
55
|
-
export interface TransactionDefinition {
|
|
56
|
-
propagation: Propagation;
|
|
57
|
-
isolationLevel?: IsolationLevel;
|
|
58
|
-
readOnly?: boolean;
|
|
59
|
-
timeout?: number;
|
|
60
|
-
name?: string;
|
|
61
|
-
dataSourceName?: string;
|
|
62
|
-
onTimeout?: TransactionTimeoutCallback;
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* 事务状态
|
|
66
|
-
*/
|
|
67
|
-
export interface TransactionStatus {
|
|
68
|
-
isCompleted: boolean;
|
|
69
|
-
isRollbackOnly: boolean;
|
|
70
|
-
isNewTransaction: boolean;
|
|
71
|
-
dataSourceName: string;
|
|
72
|
-
startTime: Date;
|
|
73
|
-
definition: TransactionDefinition;
|
|
74
|
-
nestingLevel: number;
|
|
75
|
-
timeoutTimer?: NodeJS.Timeout;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* 事务资源
|
|
79
|
-
*/
|
|
80
|
-
interface TransactionResource {
|
|
81
|
-
dataSourceName: string;
|
|
82
|
-
dataSource: DataSource;
|
|
83
|
-
queryRunner: QueryRunner;
|
|
84
|
-
transactionStarted: boolean;
|
|
85
|
-
nestingLevel: number;
|
|
86
|
-
savepoints: string[];
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* 挂起的事务资源
|
|
90
|
-
*/
|
|
91
|
-
interface SuspendedTransaction {
|
|
92
|
-
dataSourceName: string;
|
|
93
|
-
resource: TransactionResource;
|
|
94
|
-
status: TransactionStatus;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* 统一的事务上下文管理类
|
|
98
|
-
* 减少状态管理复杂度,避免不一致
|
|
99
|
-
*/
|
|
100
|
-
export declare class TransactionContextManager {
|
|
101
|
-
private readonly resources;
|
|
102
|
-
private readonly activeTransactions;
|
|
103
|
-
private readonly suspendedTransactions;
|
|
104
|
-
getResource(name: string): TransactionResource | undefined;
|
|
105
|
-
getActiveTransaction(name: string): TransactionStatus | null;
|
|
106
|
-
getAllActiveTransactions(): Map<string, TransactionStatus>;
|
|
107
|
-
getAllResources(): Map<string, TransactionResource>;
|
|
108
|
-
setResource(name: string, resource: TransactionResource): void;
|
|
109
|
-
setActiveTransaction(name: string, status: TransactionStatus): void;
|
|
110
|
-
deleteResource(name: string): boolean;
|
|
111
|
-
deleteActiveTransaction(name: string): boolean;
|
|
112
|
-
suspendTransaction(name: string): SuspendedTransaction | null;
|
|
113
|
-
resumeSuspendedTransaction(name: string): SuspendedTransaction | null;
|
|
114
|
-
clear(): void;
|
|
115
|
-
getStats(): {
|
|
116
|
-
activeTransactions: {
|
|
117
|
-
dataSource: string;
|
|
118
|
-
nestingLevel: number;
|
|
119
|
-
startTime: Date;
|
|
120
|
-
propagation: Propagation;
|
|
121
|
-
isRollbackOnly: boolean;
|
|
122
|
-
}[];
|
|
123
|
-
resources: {
|
|
124
|
-
dataSource: string;
|
|
125
|
-
hasTransaction: boolean;
|
|
126
|
-
nestingLevel: number;
|
|
127
|
-
}[];
|
|
128
|
-
suspendedTransactions: number;
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* 事务管理器
|
|
133
|
-
* 统一管理多数据源事务,支持自动嵌套
|
|
134
|
-
*/
|
|
135
|
-
export declare class TransactionManager {
|
|
136
|
-
private readonly transactionContext;
|
|
137
|
-
private readonly contextManager;
|
|
138
|
-
private readonly config?;
|
|
139
|
-
private readonly logger;
|
|
140
|
-
constructor(transactionContext: TransactionContextService, contextManager: TransactionContextManager, config?: {
|
|
141
|
-
defaultTimeout?: number;
|
|
142
|
-
defaultReadOnly?: boolean;
|
|
143
|
-
logTransactionDetails?: boolean;
|
|
144
|
-
});
|
|
145
|
-
/**
|
|
146
|
-
* 获取或创建事务
|
|
147
|
-
* 处理各种传播行为
|
|
148
|
-
*/
|
|
149
|
-
getTransaction(definition: TransactionDefinition): Promise<TransactionStatus>;
|
|
150
|
-
/**
|
|
151
|
-
* 提交事务
|
|
152
|
-
*/
|
|
153
|
-
commit(status: TransactionStatus): Promise<void>;
|
|
154
|
-
/**
|
|
155
|
-
* 回滚事务
|
|
156
|
-
*/
|
|
157
|
-
rollback(status: TransactionStatus): Promise<void>;
|
|
158
|
-
/**
|
|
159
|
-
* 获取当前事务的 EntityManager
|
|
160
|
-
*/
|
|
161
|
-
getCurrentEntityManager(dataSourceName?: string): EntityManager | null;
|
|
162
|
-
/**
|
|
163
|
-
* 获取当前事务状态
|
|
164
|
-
*/
|
|
165
|
-
getCurrentTransaction(dataSourceName?: string): TransactionStatus | null;
|
|
166
|
-
/**
|
|
167
|
-
* 获取事务统计
|
|
168
|
-
*/
|
|
169
|
-
getTransactionStats(): {
|
|
170
|
-
activeTransactions: {
|
|
171
|
-
dataSource: string;
|
|
172
|
-
nestingLevel: number;
|
|
173
|
-
startTime: Date;
|
|
174
|
-
propagation: Propagation;
|
|
175
|
-
isRollbackOnly: boolean;
|
|
176
|
-
}[];
|
|
177
|
-
resources: {
|
|
178
|
-
dataSource: string;
|
|
179
|
-
hasTransaction: boolean;
|
|
180
|
-
nestingLevel: number;
|
|
181
|
-
}[];
|
|
182
|
-
suspendedTransactions: number;
|
|
183
|
-
};
|
|
184
|
-
/**
|
|
185
|
-
* 根据 Entity 获取数据源名称
|
|
186
|
-
* 支持装饰器、静态方法和动态方法
|
|
187
|
-
*/
|
|
188
|
-
getDataSourceForEntity(entityClassOrInstance: Function | Object): string | null;
|
|
189
|
-
/**
|
|
190
|
-
* 为 Entity 获取或创建 EntityManager
|
|
191
|
-
* 自动检测 Entity 的数据源
|
|
192
|
-
*/
|
|
193
|
-
getEntityManagerForEntity(entityClassOrInstance: any, fallbackDataSourceName?: string): EntityManager | null;
|
|
194
|
-
private handleRequired;
|
|
195
|
-
private handleRequiresNew;
|
|
196
|
-
private handleNested;
|
|
197
|
-
private handleSupports;
|
|
198
|
-
private handleNotSupported;
|
|
199
|
-
private handleMandatory;
|
|
200
|
-
private handleNever;
|
|
201
|
-
private createNewTransaction;
|
|
202
|
-
private createParticipatingTransaction;
|
|
203
|
-
private getActiveTransaction;
|
|
204
|
-
private getDataSource;
|
|
205
|
-
private convertIsolationLevel;
|
|
206
|
-
private markCompleted;
|
|
207
|
-
private removeActiveTransaction;
|
|
208
|
-
private markParentForRollback;
|
|
209
|
-
private rollbackOnCommitException;
|
|
210
|
-
private cleanupResource;
|
|
211
|
-
/**
|
|
212
|
-
* 恢复挂起的事务 - 已移到 TransactionContextManager 中
|
|
213
|
-
* 此方法保留以兼容
|
|
214
|
-
*/
|
|
215
|
-
private resumeSuspendedTransaction;
|
|
216
|
-
/**
|
|
217
|
-
* 获取事务超时时间(毫秒)
|
|
218
|
-
*/
|
|
219
|
-
private getTimeoutMs;
|
|
220
|
-
/**
|
|
221
|
-
* 处理事务超时
|
|
222
|
-
*/
|
|
223
|
-
private handleTransactionTimeout;
|
|
224
|
-
/**
|
|
225
|
-
* 清理事务定时器
|
|
226
|
-
* 确保定时器被正确清理,避免内存泄漏
|
|
227
|
-
*/
|
|
228
|
-
private clearTimeout;
|
|
229
|
-
}
|
|
230
|
-
export {};
|