I got tired of threading the EntityManager/QueryRunner through every layer of a modular NestJS backend—passing it as a parameter into every service and method. It was noisy, brittle, and honestly, a pain. I went hunting for a decorator-based solution for TypeORM transactions. I found a few, tried them, but they felt overconfigured and, crucially, the same transaction didn’t reliably propagate into deeply nested calls. Maybe I misused them—but the DX wasn’t there.
So I built typeorm-transactional-decorator: a small, focused layer that uses Node’s async hooks to carry a transactional context and patches TypeORM’s DataSource/EntityManager so repositories automatically bind to the current transaction if one exists. You get a dead-simple @Transactional decorator, @IgnoreTransaction to opt out where needed, reliable propagation into nested methods, automatic rollback on errors, and a TransactionResultManager to register side effects for onCommit/onRollback (think: delete an S3 file if the DB transaction fails). It’s based on typeorm-transactional, but simplified and tuned for a predictable, minimal workflow.
It slots neatly into NestJS via TypeOrmModule’s dataSourceFactory, or you can call addTransactionalDataSource(dataSource) in any Node app. The package grows as my needs evolve, but the north star is the same: minimal API, maximum ergonomics for real-world, layered architectures.
How are you handling TypeORM transactions?
NPM: https://www.npmjs.com/package/typeorm-transactional-decorator
» npm install @nestjs-cls/transactional
» npm install @hodfords/nestjs-transaction
Thanks everyone, I just found the problem is I can't chain the save() right after create() which will call the entity's save() fn instead of the entityManager's one, and start a new transaction.
async createPrice(dto, entityManager){
//wrong code
return entityManager.create(PriceEntity, {...}).save();
//works
const price = entityManager.create(PriceEntity, {...});
return entityManager.save(price);
}
}
try to add @Transactional() decorator before insert function from your services typeorm transaction/ typeorm-transactional-cls-hooked
@Transactional()
public async createProduct(...) {
...
}
Hello everyone,
I have been looking online for a nice way to handle database transactions in NestJs.
I looked at the examples in the docs and I read some articles online, but they all revolve around passing the EntityManager around.
I am guessing that I can't be the only one looking for a better alternative as passing that object around different methods across your codebase doesn't bother me only.
So, I am curious, did anyone find a better alternative to this? To somehow hide and abstract away the EntityManager?
Looking forward to hearing your thoughts!
Many thanks!