transaction-interceptor.ts 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
  2. import { Reflector } from '@nestjs/core';
  3. import { Observable, of } from 'rxjs';
  4. import { internal_getRequestContext, internal_setRequestContext, RequestContext } from '..';
  5. import { TransactionWrapper } from '../../connection/transaction-wrapper';
  6. import { TransactionalConnection } from '../../connection/transactional-connection';
  7. import { parseContext } from '../common/parse-context';
  8. import {
  9. TRANSACTION_ISOLATION_LEVEL_METADATA_KEY,
  10. TRANSACTION_MODE_METADATA_KEY,
  11. TransactionIsolationLevel,
  12. TransactionMode,
  13. } from '../decorators/transaction.decorator';
  14. /**
  15. * @description
  16. * Used by the {@link Transaction} decorator to create a transactional query runner
  17. * and attach it to the RequestContext.
  18. */
  19. @Injectable()
  20. export class TransactionInterceptor implements NestInterceptor {
  21. constructor(
  22. private connection: TransactionalConnection,
  23. private transactionWrapper: TransactionWrapper,
  24. private reflector: Reflector,
  25. ) {}
  26. intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
  27. const { req } = parseContext(context);
  28. const ctx: RequestContext | undefined = internal_getRequestContext(req, context);
  29. if (ctx) {
  30. const transactionMode = this.reflector.get<TransactionMode>(
  31. TRANSACTION_MODE_METADATA_KEY,
  32. context.getHandler(),
  33. );
  34. const transactionIsolationLevel = this.reflector.get<TransactionIsolationLevel | undefined>(
  35. TRANSACTION_ISOLATION_LEVEL_METADATA_KEY,
  36. context.getHandler(),
  37. );
  38. return of(
  39. this.transactionWrapper.executeInTransaction(
  40. ctx,
  41. _ctx => {
  42. // Registers transactional request context associated
  43. // with execution handler function
  44. internal_setRequestContext(req, _ctx, context);
  45. return next.handle();
  46. },
  47. transactionMode,
  48. transactionIsolationLevel,
  49. this.connection.rawConnection,
  50. ),
  51. );
  52. } else {
  53. return next.handle();
  54. }
  55. }
  56. }