@tsed/mikro-orm 6.116.6 → 6.117.2
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/lib/cjs/interceptors/TransactionalInterceptor.d.ts +2 -0
- package/lib/cjs/interceptors/TransactionalInterceptor.js +13 -7
- package/lib/cjs/interceptors/TransactionalInterceptor.js.map +1 -1
- package/lib/esm/interceptors/TransactionalInterceptor.js +13 -7
- package/lib/esm/interceptors/TransactionalInterceptor.js.map +1 -1
- package/lib/types/interceptors/TransactionalInterceptor.d.ts +2 -0
- package/package.json +10 -10
- package/readme.md +14 -0
|
@@ -3,8 +3,10 @@ import { Logger } from "@tsed/logger";
|
|
|
3
3
|
import { RetryStrategy } from "../services/RetryStrategy";
|
|
4
4
|
import { MikroOrmContext } from "../services/MikroOrmContext";
|
|
5
5
|
import { MikroOrmRegistry } from "../services/MikroOrmRegistry";
|
|
6
|
+
import { IsolationLevel } from "@mikro-orm/core";
|
|
6
7
|
export interface TransactionOptions {
|
|
7
8
|
retry?: boolean;
|
|
9
|
+
isolationLevel?: IsolationLevel;
|
|
8
10
|
contextName?: string;
|
|
9
11
|
/**
|
|
10
12
|
* @deprecated Since 2022-02-01. Use {@link contextName} instead
|
|
@@ -7,6 +7,7 @@ const logger_1 = require("@tsed/logger");
|
|
|
7
7
|
const RetryStrategy_1 = require("../services/RetryStrategy");
|
|
8
8
|
const MikroOrmContext_1 = require("../services/MikroOrmContext");
|
|
9
9
|
const MikroOrmRegistry_1 = require("../services/MikroOrmRegistry");
|
|
10
|
+
const core_1 = require("@mikro-orm/core");
|
|
10
11
|
let TransactionalInterceptor = class TransactionalInterceptor {
|
|
11
12
|
registry;
|
|
12
13
|
context;
|
|
@@ -29,7 +30,7 @@ let TransactionalInterceptor = class TransactionalInterceptor {
|
|
|
29
30
|
return this.runWithinNewCtx(next, options);
|
|
30
31
|
}
|
|
31
32
|
runWithinCtx(next, options) {
|
|
32
|
-
const callback = () => this.executeInTransaction(
|
|
33
|
+
const callback = () => this.executeInTransaction(next, options);
|
|
33
34
|
return options.retry && this.retryStrategy ? this.retryStrategy.acquire(callback) : callback();
|
|
34
35
|
}
|
|
35
36
|
runWithinNewCtx(next, options) {
|
|
@@ -41,6 +42,7 @@ let TransactionalInterceptor = class TransactionalInterceptor {
|
|
|
41
42
|
}
|
|
42
43
|
extractContextName(context) {
|
|
43
44
|
const options = context.options || {};
|
|
45
|
+
let isolationLevel;
|
|
44
46
|
let contextName;
|
|
45
47
|
let retry;
|
|
46
48
|
if (typeof options === "string") {
|
|
@@ -48,6 +50,7 @@ let TransactionalInterceptor = class TransactionalInterceptor {
|
|
|
48
50
|
}
|
|
49
51
|
else if (options) {
|
|
50
52
|
contextName = options.contextName ?? options.connectionName;
|
|
53
|
+
isolationLevel = options.isolationLevel;
|
|
51
54
|
retry = options.retry;
|
|
52
55
|
}
|
|
53
56
|
if (!contextName) {
|
|
@@ -56,13 +59,16 @@ let TransactionalInterceptor = class TransactionalInterceptor {
|
|
|
56
59
|
if (!retry) {
|
|
57
60
|
retry = false;
|
|
58
61
|
}
|
|
59
|
-
|
|
62
|
+
if (!isolationLevel) {
|
|
63
|
+
isolationLevel = core_1.IsolationLevel.READ_COMMITTED;
|
|
64
|
+
}
|
|
65
|
+
return { contextName, isolationLevel, retry };
|
|
60
66
|
}
|
|
61
|
-
async executeInTransaction(
|
|
62
|
-
const manager = this.context.get(contextName);
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
async executeInTransaction(next, options) {
|
|
68
|
+
const manager = this.context.get(options.contextName);
|
|
69
|
+
return manager.transactional(() => next(), {
|
|
70
|
+
isolationLevel: options.isolationLevel
|
|
71
|
+
});
|
|
66
72
|
}
|
|
67
73
|
};
|
|
68
74
|
TransactionalInterceptor = tslib_1.__decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransactionalInterceptor.js","sourceRoot":"","sources":["../../../src/interceptors/TransactionalInterceptor.ts"],"names":[],"mappings":";;;;AAAA,iCAAsG;AACtG,yCAAoC;AACpC,6DAAwD;AACxD,iEAA4D;AAC5D,mEAA8D;
|
|
1
|
+
{"version":3,"file":"TransactionalInterceptor.js","sourceRoot":"","sources":["../../../src/interceptors/TransactionalInterceptor.ts"],"names":[],"mappings":"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","sourcesContent":["import {Inject, Interceptor, InterceptorContext, InterceptorMethods, InterceptorNext} from \"@tsed/di\";\nimport {Logger} from \"@tsed/logger\";\nimport {RetryStrategy} from \"../services/RetryStrategy\";\nimport {MikroOrmContext} from \"../services/MikroOrmContext\";\nimport {MikroOrmRegistry} from \"../services/MikroOrmRegistry\";\nimport {IsolationLevel} from \"@mikro-orm/core\";\n\nexport interface TransactionOptions {\n retry?: boolean;\n isolationLevel?: IsolationLevel;\n contextName?: string;\n /**\n * @deprecated Since 2022-02-01. Use {@link contextName} instead\n */\n connectionName?: string;\n}\n\ntype TransactionSettings = Required<Omit<TransactionOptions, \"connectionName\">>;\n\n@Interceptor()\nexport class TransactionalInterceptor implements InterceptorMethods {\n constructor(\n @Inject() private readonly registry: MikroOrmRegistry,\n @Inject() private readonly context: MikroOrmContext,\n @Inject() private readonly logger: Logger,\n @Inject(RetryStrategy)\n private readonly retryStrategy?: RetryStrategy\n ) {}\n\n public async intercept(context: InterceptorContext<unknown>, next: InterceptorNext): Promise<unknown> {\n const options = this.extractContextName(context);\n\n if (options.retry && !this.retryStrategy) {\n this.logger.warn(`To retry a transaction you have to implement a \"${RetryStrategy.description}\" interface`);\n }\n\n if (this.context.has(options.contextName)) {\n return this.runWithinCtx(next, options);\n }\n\n return this.runWithinNewCtx(next, options);\n }\n\n private runWithinCtx(next: InterceptorNext, options: TransactionSettings): Promise<unknown> | unknown {\n const callback = () => this.executeInTransaction(next, options);\n\n return options.retry && this.retryStrategy ? this.retryStrategy.acquire(callback) : callback();\n }\n\n private runWithinNewCtx(next: InterceptorNext, options: TransactionSettings): Promise<unknown> | unknown {\n const orm = this.registry.get(options.contextName);\n\n if (!orm) {\n throw new Error(\n `No such context: ${options.contextName}. Please register a corresponding MikroOrm instance using '@Configuration()' decorator.`\n );\n }\n\n return this.context.run([orm.em], () => this.runWithinCtx(next, options));\n }\n\n private extractContextName(context: InterceptorContext<unknown>): TransactionSettings {\n const options = context.options || ({} as TransactionOptions | string);\n\n let isolationLevel: IsolationLevel | undefined;\n let contextName: string | undefined;\n let retry: boolean | undefined;\n\n if (typeof options === \"string\") {\n contextName = options;\n } else if (options) {\n contextName = options.contextName ?? options.connectionName;\n isolationLevel = options.isolationLevel;\n retry = options.retry;\n }\n\n if (!contextName) {\n contextName = \"default\";\n }\n\n if (!retry) {\n retry = false;\n }\n\n if (!isolationLevel) {\n isolationLevel = IsolationLevel.READ_COMMITTED;\n }\n\n return {contextName, isolationLevel, retry};\n }\n\n private async executeInTransaction(next: InterceptorNext, options: TransactionSettings): Promise<unknown> {\n const manager = this.context.get(options.contextName)!;\n\n return manager.transactional(() => next(), {\n isolationLevel: options.isolationLevel\n });\n }\n}\n"]}
|
|
@@ -4,6 +4,7 @@ import { Logger } from "@tsed/logger";
|
|
|
4
4
|
import { RetryStrategy } from "../services/RetryStrategy.js";
|
|
5
5
|
import { MikroOrmContext } from "../services/MikroOrmContext.js";
|
|
6
6
|
import { MikroOrmRegistry } from "../services/MikroOrmRegistry.js";
|
|
7
|
+
import { IsolationLevel } from "@mikro-orm/core";
|
|
7
8
|
let TransactionalInterceptor = class TransactionalInterceptor {
|
|
8
9
|
registry;
|
|
9
10
|
context;
|
|
@@ -26,7 +27,7 @@ let TransactionalInterceptor = class TransactionalInterceptor {
|
|
|
26
27
|
return this.runWithinNewCtx(next, options);
|
|
27
28
|
}
|
|
28
29
|
runWithinCtx(next, options) {
|
|
29
|
-
const callback = () => this.executeInTransaction(
|
|
30
|
+
const callback = () => this.executeInTransaction(next, options);
|
|
30
31
|
return options.retry && this.retryStrategy ? this.retryStrategy.acquire(callback) : callback();
|
|
31
32
|
}
|
|
32
33
|
runWithinNewCtx(next, options) {
|
|
@@ -38,6 +39,7 @@ let TransactionalInterceptor = class TransactionalInterceptor {
|
|
|
38
39
|
}
|
|
39
40
|
extractContextName(context) {
|
|
40
41
|
const options = context.options || {};
|
|
42
|
+
let isolationLevel;
|
|
41
43
|
let contextName;
|
|
42
44
|
let retry;
|
|
43
45
|
if (typeof options === "string") {
|
|
@@ -45,6 +47,7 @@ let TransactionalInterceptor = class TransactionalInterceptor {
|
|
|
45
47
|
}
|
|
46
48
|
else if (options) {
|
|
47
49
|
contextName = options.contextName ?? options.connectionName;
|
|
50
|
+
isolationLevel = options.isolationLevel;
|
|
48
51
|
retry = options.retry;
|
|
49
52
|
}
|
|
50
53
|
if (!contextName) {
|
|
@@ -53,13 +56,16 @@ let TransactionalInterceptor = class TransactionalInterceptor {
|
|
|
53
56
|
if (!retry) {
|
|
54
57
|
retry = false;
|
|
55
58
|
}
|
|
56
|
-
|
|
59
|
+
if (!isolationLevel) {
|
|
60
|
+
isolationLevel = IsolationLevel.READ_COMMITTED;
|
|
61
|
+
}
|
|
62
|
+
return { contextName, isolationLevel, retry };
|
|
57
63
|
}
|
|
58
|
-
async executeInTransaction(
|
|
59
|
-
const manager = this.context.get(contextName);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
async executeInTransaction(next, options) {
|
|
65
|
+
const manager = this.context.get(options.contextName);
|
|
66
|
+
return manager.transactional(() => next(), {
|
|
67
|
+
isolationLevel: options.isolationLevel
|
|
68
|
+
});
|
|
63
69
|
}
|
|
64
70
|
};
|
|
65
71
|
TransactionalInterceptor = __decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransactionalInterceptor.js","sourceRoot":"","sources":["../../../src/interceptors/TransactionalInterceptor.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,MAAM,EAAE,WAAW,EAA0D,MAAM,UAAU,CAAC;AACtG,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AACpC,OAAO,EAAC,aAAa,EAAC,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAC,eAAe,EAAC,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAC,gBAAgB,EAAC,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"TransactionalInterceptor.js","sourceRoot":"","sources":["../../../src/interceptors/TransactionalInterceptor.ts"],"names":[],"mappings":"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","sourcesContent":["import {Inject, Interceptor, InterceptorContext, InterceptorMethods, InterceptorNext} from \"@tsed/di\";\nimport {Logger} from \"@tsed/logger\";\nimport {RetryStrategy} from \"../services/RetryStrategy\";\nimport {MikroOrmContext} from \"../services/MikroOrmContext\";\nimport {MikroOrmRegistry} from \"../services/MikroOrmRegistry\";\nimport {IsolationLevel} from \"@mikro-orm/core\";\n\nexport interface TransactionOptions {\n retry?: boolean;\n isolationLevel?: IsolationLevel;\n contextName?: string;\n /**\n * @deprecated Since 2022-02-01. Use {@link contextName} instead\n */\n connectionName?: string;\n}\n\ntype TransactionSettings = Required<Omit<TransactionOptions, \"connectionName\">>;\n\n@Interceptor()\nexport class TransactionalInterceptor implements InterceptorMethods {\n constructor(\n @Inject() private readonly registry: MikroOrmRegistry,\n @Inject() private readonly context: MikroOrmContext,\n @Inject() private readonly logger: Logger,\n @Inject(RetryStrategy)\n private readonly retryStrategy?: RetryStrategy\n ) {}\n\n public async intercept(context: InterceptorContext<unknown>, next: InterceptorNext): Promise<unknown> {\n const options = this.extractContextName(context);\n\n if (options.retry && !this.retryStrategy) {\n this.logger.warn(`To retry a transaction you have to implement a \"${RetryStrategy.description}\" interface`);\n }\n\n if (this.context.has(options.contextName)) {\n return this.runWithinCtx(next, options);\n }\n\n return this.runWithinNewCtx(next, options);\n }\n\n private runWithinCtx(next: InterceptorNext, options: TransactionSettings): Promise<unknown> | unknown {\n const callback = () => this.executeInTransaction(next, options);\n\n return options.retry && this.retryStrategy ? this.retryStrategy.acquire(callback) : callback();\n }\n\n private runWithinNewCtx(next: InterceptorNext, options: TransactionSettings): Promise<unknown> | unknown {\n const orm = this.registry.get(options.contextName);\n\n if (!orm) {\n throw new Error(\n `No such context: ${options.contextName}. Please register a corresponding MikroOrm instance using '@Configuration()' decorator.`\n );\n }\n\n return this.context.run([orm.em], () => this.runWithinCtx(next, options));\n }\n\n private extractContextName(context: InterceptorContext<unknown>): TransactionSettings {\n const options = context.options || ({} as TransactionOptions | string);\n\n let isolationLevel: IsolationLevel | undefined;\n let contextName: string | undefined;\n let retry: boolean | undefined;\n\n if (typeof options === \"string\") {\n contextName = options;\n } else if (options) {\n contextName = options.contextName ?? options.connectionName;\n isolationLevel = options.isolationLevel;\n retry = options.retry;\n }\n\n if (!contextName) {\n contextName = \"default\";\n }\n\n if (!retry) {\n retry = false;\n }\n\n if (!isolationLevel) {\n isolationLevel = IsolationLevel.READ_COMMITTED;\n }\n\n return {contextName, isolationLevel, retry};\n }\n\n private async executeInTransaction(next: InterceptorNext, options: TransactionSettings): Promise<unknown> {\n const manager = this.context.get(options.contextName)!;\n\n return manager.transactional(() => next(), {\n isolationLevel: options.isolationLevel\n });\n }\n}\n"]}
|
|
@@ -3,8 +3,10 @@ import { Logger } from "@tsed/logger";
|
|
|
3
3
|
import { RetryStrategy } from "../services/RetryStrategy";
|
|
4
4
|
import { MikroOrmContext } from "../services/MikroOrmContext";
|
|
5
5
|
import { MikroOrmRegistry } from "../services/MikroOrmRegistry";
|
|
6
|
+
import { IsolationLevel } from "@mikro-orm/core";
|
|
6
7
|
export interface TransactionOptions {
|
|
7
8
|
retry?: boolean;
|
|
9
|
+
isolationLevel?: IsolationLevel;
|
|
8
10
|
contextName?: string;
|
|
9
11
|
/**
|
|
10
12
|
* @deprecated Since 2022-02-01. Use {@link contextName} instead
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsed/mikro-orm",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.117.2",
|
|
4
4
|
"description": "MikroORM package for Ts.ED framework",
|
|
5
5
|
"private": false,
|
|
6
6
|
"source": "./src/index.ts",
|
|
@@ -26,20 +26,20 @@
|
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@mikro-orm/core": "^5.2.2",
|
|
28
28
|
"@mikro-orm/mongodb": "^5.2.2",
|
|
29
|
-
"@tsed/common": "6.
|
|
30
|
-
"@tsed/core": "6.
|
|
31
|
-
"@tsed/di": "6.
|
|
32
|
-
"@tsed/json-mapper": "6.
|
|
29
|
+
"@tsed/common": "6.117.2",
|
|
30
|
+
"@tsed/core": "6.117.2",
|
|
31
|
+
"@tsed/di": "6.117.2",
|
|
32
|
+
"@tsed/json-mapper": "6.117.2",
|
|
33
33
|
"@tsed/logger": ">=6.2.0",
|
|
34
|
-
"@tsed/schema": "6.
|
|
35
|
-
"@tsed/testing-mongoose": "6.
|
|
34
|
+
"@tsed/schema": "6.117.2",
|
|
35
|
+
"@tsed/testing-mongoose": "6.117.2",
|
|
36
36
|
"ts-mockito": "^2.6.1"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@mikro-orm/core": ">=4.5.9",
|
|
40
|
-
"@tsed/common": "^6.
|
|
41
|
-
"@tsed/core": "^6.
|
|
42
|
-
"@tsed/di": "^6.
|
|
40
|
+
"@tsed/common": "^6.117.2",
|
|
41
|
+
"@tsed/core": "^6.117.2",
|
|
42
|
+
"@tsed/di": "^6.117.2",
|
|
43
43
|
"@tsed/logger": ">=6.2.0"
|
|
44
44
|
},
|
|
45
45
|
"repository": "https://github.com/tsedio/tsed",
|
package/readme.md
CHANGED
|
@@ -353,6 +353,20 @@ export class UsersCtrl {
|
|
|
353
353
|
}
|
|
354
354
|
```
|
|
355
355
|
|
|
356
|
+
## Transaction isolation levels
|
|
357
|
+
|
|
358
|
+
By default, `IsolationLevel.READ_COMMITTED` is used. You can override it, specifying the isolation level for the transaction by supplying it as the `isolationLevel` parameter in the `@Transactional` decorator:
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
@Post("/")
|
|
362
|
+
@Transactional({isolationLevel: IsolationLevel.SERIALIZABLE})
|
|
363
|
+
create(@BodyParams() user: User): Promise<User> {
|
|
364
|
+
return this.usersService.create(user);
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
The MikroORM supports the standard isolation levels such as `SERIALIZABLE` or `REPEATABLE READ`, the full list of available options see [here](https://mikro-orm.io/docs/transactions#isolation-levels).
|
|
369
|
+
|
|
356
370
|
## Contributors
|
|
357
371
|
|
|
358
372
|
Please read [contributing guidelines here](https://tsed.io/CONTRIBUTING.html)
|