odavid / typeorm-transactional-cls-hooked

A Transactional Method Decorator for typeorm that uses cls-hooked to handle and propagate transactions between different repositories and service methods. Inpired by Spring Trasnactional Annotation and Sequelize CLS
MIT License
524 stars 86 forks source link

How to commit the transaction? #87

Open stovberpv opened 3 years ago

stovberpv commented 3 years ago

Hi there. Thx for this awesome library, but i have one question about the transactions. How to commit a transaction when using the `@Transactional () ' decorator?

@Transactional()
async myAwesomeMethod(): Promise<void> {
  await this.repository.save(...);

  // <-- how can i commit a transaction before an exception occurs? 

  throw new Error();
}
koenpunt commented 3 years ago

I can imagine that it should be possible for the library to catch a specific Symbol being thrown.

So to commit you would do something like this:

import { ...., CommitTransaction } from 'typeorm-transactional-cls-hooked';

@Transactional()
async myAwesomeMethod(): Promise<void> {
  await this.repository.save(...);

  throw CommitTransaction;
  // <-- how can i commit a transaction before an exception occurs? 

  throw new Error();
}
stovberpv commented 3 years ago

But then it will interrupt the execution of the function? How to make a commit without interrupting the function?

H4ad commented 3 years ago

I handle these cases with this pattern:

@Transactional()
async myAwesomeMethod(): Promise<void> {
  await this.runAndCommit();

 // now you can throw an error without worry of transaction is not being commited.
  throw new Error();
}

// requires new in propagation forces the lib to create another transaction
@Transactional({ propagation: Propagation.REQUIRES_NEW })
async runAndCommit(): Promise<void>{ 
  // do your things and after this method runs, the transaction is commited
  // even if this method is called by a method wrapped by another transaction.

  await this.repository.save(...);
}
Beloin commented 3 years ago

@H4ad case worked for me.

Just needs to remember to set in the case we really need.