Many solutions are available, they should all be based on SQL transaction management.

Personally I feel that the simplest way to achieve that is to use the same EntityManager instance when you execute code on your database. Then you can use something like:

getConnection().transaction(entityManager -> {
    service1.doStuff1(entityManager);
    service2.doStuff2(entityManager);
});

You can spawn a QueryRunner from an EntityManager instance that will be wrapped in the same transaction in case you execute raw SQL outside ORM operations. You need also to spawn Repository instances from EntityManager as well or they will execute code outside the main transaction.

Answer from zenbeni on Stack Overflow
🌐
Medium
medium.com › @dev.muhammet.ozen › advanced-transaction-management-with-nestjs-typeorm-43a839363491
Advanced Transaction Management with NestJS & TypeORM | by Muhammet Özen | Medium
September 17, 2023 - As I stated above, this is a simple approach where we create a query runner, get a connection, start a transaction, and execute all queries over that query runner. Imagine we have two TypeORM entities as Order and Item .
Discussions

how to use transaction across service in nestjs with typeorm - Stack Overflow
How can I have a transaction across different service in my project? I try my code as below but the transaction doesn't rollback while exception threw. The following code will rollback as expected... More on stackoverflow.com
🌐 stackoverflow.com
TypeORM - it's not what you think.
I remember when typeorm had a bug where delete queries were dropping the where clause and the maintainer tried to argue it was by design. Bye bye tables lol More on reddit.com
🌐 r/typescript
116
182
March 3, 2021
TypeORM Sucks!! Something I wanted to talk about since long!
Welcome to 95% of the ORMs. I still don't understand why you have to learn a bad DSL over a language that every backend developer should know... More on reddit.com
🌐 r/typescript
112
111
October 17, 2020
TypeGraphql/TypeORM best practices
Are you defining your TypeORM entities and schema models inside the same class, using decorators from both libs alongside each other? Or do you split it into two classes in two separate files? Any other sources for best practices? I’m using all of this on top of NestJS If it matters. More on reddit.com
🌐 r/graphql
11
14
November 10, 2019
🌐
Reddit
reddit.com › r/nestjs › how can i use transactions with typeorm across multiple services
r/nestjs on Reddit: How can I use transactions with typeorm across multiple services
January 21, 2024 -

This is my current code, it supposed to start a transaction in the update method that used other services.

  async update(authContext: AuthContext, id: string, updatePortfolioDto: UpdatePortfolioDto, isSaved = false): Promise<Portfolio> {

    const queryRunner = this.dataSource.createQueryRunner();

  await queryRunner.connect();
  await queryRunner.startTransaction();
  try{
    await this.sleeveService.deleteForPortfolio(authContext, id);
    const updatedPortfolio = this.portfoliosRepository.update(id, portfolio);
    await queryRunner.commitTransaction();
    return updatedPortfolio

  }catch(err){
    await queryRunner.rollbackTransaction();
  }finally{
    await queryRunner.release();
  }
  }

As you can see, I am calling a method from another sevice and repository.

For example deleteForPortfolio method in the sleeveservice is

export class TypeOrmSleeveRepository implements ISleevesRepository {
  private readonly logger = new Logger(TypeOrmSleeveRepository.name);

  constructor(@InjectRepository(Sleeve) private readonly sleeveRepository: Repository<Sleeve>) {}

  deleteForPortfolio(authContext: AuthContext, portfolioId: string) {
    this.sleeveRepository
      .createQueryBuilder('sleeve')
      .delete()
      .where('sleeve.portfolioId = :portfolioId', { portfolioId })
      .andWhere('sleeve.tenantId = :tenantId', { tenantId: authContext.tenantId })
      .execute();
  }
}

and the portfolio update method is

  async update(id: string, portfolio: Portfolio): Promise<Portfolio> {
    try {
      const updatedPortfolio = await this.portfolioRepository.preload({
        id,
        ...portfolio
      });

      if (!updatedPortfolio) {
        this.logger.warn(`Portfolio with ID ${id} not found`);
        throw new NotFoundException(`Portfolio with ID ${id} not found`);
      }
      const savedPortfolio = await this.portfolioRepository.save(updatedPortfolio);
      this.logger.log(`Updated Portfolio with ID ${id}`);
      return savedPortfolio;
    } catch (error) {
      if (error instanceof NotFoundException) {
        throw error;
      }
      this.logger.error(`Error updating portfolio with ID ${id}: ${error.message}`, error.stack);
      throw error;
    }
  }

Currently my code does not work. How can I fix this please ?

🌐
DEV Community
dev.to › alphamikle › the-easiest-way-to-use-transactions-in-nest-js-41h0
The easiest way to use transactions in Nest.js - DEV Community
February 13, 2021 - To build the queries, TypeORM was used, which we will return to a little later. The ORM and Postgres settings are set by default, so each operation will be performed in its own transaction, but to take advantage of this advantage, you need to write one query in which all the logic associated with the database will take place at once. Below is an example of the execution of multiple queries executed in one transaction:
🌐
Medium
medium.com › @alperenergul49 › understanding-typeorm-transactions-a-step-by-step-guide-with-nest-js-f682b63b514a
Understanding TypeORM Transactions: A Step-by-Step Guide with Nest.js | by Alperen Ergul | Oct, 2024 | Medium | Medium
March 21, 2025 - Today I will explain what a transaction is, what it does and how to use it in TypeOrm. Transaction ensures that a series of database operations (e.g. inserts, deletes, updates) are completed successfully or undone as if none of them had been done. It is used to maintain integrity, consistency and security in database systems. Transaction basically means the execution of one or more transactions as an atomic (indivisible) unit. In this guide, I will explain this topic through an example.
🌐
HackerNoon
hackernoon.com › the-most-convenient-ways-of-writing-transactions-within-the-nestjs-typeorm-stack-3q3q33jd
The Most Convenient Ways of Writing Transactions Within the Nest.js + TypeORM Stack | HackerNoon
February 28, 2021 - To build the queries, TypeORM was used, which we will return to a little later. The ORM and Postgres settings are set by default, so each operation will be performed in its own transaction, but to take advantage of this advantage, you need to write one query in which all the logic associated with the database will take place at once. Below is an example of the execution of multiple queries executed in one transaction:
🌐
Better Programming
betterprogramming.pub › handling-transactions-in-typeorm-and-nest-js-with-ease-3a417e6ab5
Handling Transactions in TypeORM and Nest.js With Ease | by Dmitry Shamshurin | Better Programming
April 6, 2022 - Use decorators to control the transaction (@Transaction() and @TransactionManager()), which is not recommended by the Nest.js docs. Include some 3rd party library like typeorm-transactional-cls-hooked (which is based on this cool “Continuation Local Storage” concept) or nest_transact.
Find elsewhere
🌐
GitHub
github.com › alphamikle › nest_transact
GitHub - alphamikle/nest_transact: Simplest transactions support for Nestjs with Typeorm · GitHub
It can be, for example, some cache services, or anything, which you don't want to recreate and which is not a part of transaction logic: // ./example/src/transfer/info.controller.ts import { Controller, Get } from '@nestjs/common'; import { DataSource } from 'typeorm'; import { InfoService } from './info.service'; import { CacheService } from './cache.service'; @Controller('info') export class InfoController { constructor( private readonly infoService: InfoService, private readonly dataSource: DataSource, ) { } @Get() async getInfo() { return this.dataSource.transaction(manager => { return this.infoService.withTransaction(manager, { excluded: [CacheService] }).getInfo(); }); } }
Starred by 119 users
Forked by 20 users
Languages   TypeScript 94.9% | Shell 3.1% | JavaScript 1.9% | Dockerfile 0.1%
🌐
Medium
medium.com › @neerajsonii › ninja-way-of-handling-database-transactions-with-typeorm-in-nestjs-be95241b24d9
Ninja way of handling Database Transactions with Typeorm in NestJs. | by Neeraj Soni | Medium
December 19, 2022 - A transaction class will create a transaction object and return. import { DataSource } from 'typeorm'; export class DbTransaction { private queryRunner = DataSource.createQueryRunner(); constructor() {} async start(): Promise<TransactionRunner> { return this.queryRunner.connect(); } async commitTransaction(): Promise<void> { return this.queryRunner.commitTransaction(); } async rollbackTransaction(): Promise<void> { return this.queryRunner.rollbackTransaction(); } async release(): Promise<void> { return this.queryRunner.release(); } }
🌐
Aaron Boman
aaronboman.com › programming › 2020 › 05 › 15 › per-request-database-transactions-with-nestjs-and-typeorm
Per-Request Database Transactions with NestJS and TypeORM – Aaron Boman
July 12, 2024 - Transactional security is a very important feature and not realizing that or implementing it defectively, or (as in my case) assuming that it is baked-in must have caused a lot of nestjs bugs already. IMO the best implementation to bake it in is having @InjectTransactionalRepository similar to @InjectRepository of @nestjs/typeorm(or with an argument for InjectRespositor, which is unlikely considering that current repos are app scoped).
🌐
PROGRESSIVE CODER
progressivecoder.com › home › blog › how to perform a nestjs typeorm transaction using queryrunner?
How to perform a NestJS TypeORM Transaction using QueryRunner?
February 10, 2023 - Then, we save all the books (in this case 2 books) as part of the same transaction. If something goes wrong, we rollback everything. Else, we commit the transaction and release the connection. With this, we are done with NestJS TypeORM Transaction using QueryRunner.
🌐
DZone
dzone.com › data engineering › databases › how to perform a nestjs typeorm transaction using queryrunner?
NestJS TypeORM Transaction Using QueryRunner
October 31, 2021 - Then, we save all the books (in this case 2 books) as part of the same transaction. If something goes wrong, we rollback everything. Else, we commit the transaction and release the connection. With this, we are done with NestJS TypeORM Transaction using QueryRunner.
🌐
Medium
medium.com › @jsankit99 › transaction-management-in-nestjs-typeorm-3-3-the-transactional-decorator-7fd60466b8a4
Transaction Management in NestJS + TypeORM (3/3): The @Transactional Decorator | by Ankit Pradhan | Medium
January 28, 2026 - @Injectable() export class OrderService { @Transactional() async createOrder(userId: string, items: OrderItem[]) { const order = await this.orderRepo.save({ userId, items }); await this.inventoryService.reserveItems(items); return order; } } Much cleaner! That’s what we’re building. import { SetMetadata } from '@nestjs/common'; import { IsolationLevel } from 'typeorm/driver/types/IsolationLevel'; // Metadata key used to identify transactional methods export const TRANSACTIONAL_KEY = Symbol('TRANSACTIONAL_METHOD'); /** * Marks a method as transactional.
🌐
Wanago
wanago.io › home › api with nestjs #15. defining transactions with postgresql and typeorm
API with NestJS #15. Defining transactions with PostgreSQL and TypeORM
October 26, 2020 - The official TypeORM documentation mentions a few options for defining transactions. On the other hand, the NestJS documentation seems to be set on just one of them that involves using the QueryRunner.
🌐
Bytesmith
bytesmith.dev › blog › 20240320-nestjs-transactions
How I Harnessed Transactions in NestJS with TypeORM ...
March 19, 2024 - Launch your MVP in 30 days. ByteSmith is a precision-engineered boutique software studio that builds scalable, high-performance applications.
🌐
JavaScript in Plain English
javascript.plainenglish.io › how-i-harnessed-transactions-in-nestjs-with-typeorm-without-a-headache-e901aee7aff7
How I Harnessed Transactions in NestJS with TypeORM Without a Headache | JavaScript in Plain English
March 24, 2024 - A big challenge came up when I looked into using NestJS's interceptor layer, which only works for the Controller layer. This meant that every time a request was made, a transaction would start. This wasn't efficient and added too many restrictions.
🌐
Medium
medium.com › @ash_s_r1 › how-to-run-queries-in-a-transaction-on-nest-js-with-typeorm-cb9356d4e535
How to run queries in a transaction on nest.js with TypeORM | by Ash | Medium
July 25, 2020 - When we use nest.js in TypeORM app, we may use Repository<Entity> in Service modules. But, how about transactions? I found an easy way to do it. Besides, connection is injected by TypeOrnModule. Typescript · Nestjs · Typeorm · 1 follower · ·1 following ·