Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@AfterSave(): Unlike other events @AfterSave() Commits transaction before broadcasting the event #10269

Open
18 tasks
HassanAmed opened this issue Aug 9, 2023 · 1 comment

Comments

@HassanAmed
Copy link

Feature Description

Description: This request has been mentioned by community in #1705 #743 #7664 #6450. I do understand the design choice that events are an extension of ongoing transaction but there are cases where actions need to be performed after the transaction is committed as well so instead of changing @AfterInsert() behavior a new event @AftreSave() should be added to allow handling of such cases.

Use case: I am saving payments and orders. As soon as an order is created I need to make a blockchain transaction to process that order. I make this transaction inside @AfterInsert() but blockchain transactions can fail for several reasons which end up reverting the order placed for which a user has already paid for.

Expected Behaviour: The order must be saved regardless of the blockchain transaction result which can be retried if failed.

We could also add @AfterUpdateCommit() as mentioned here with similar behavior

The Solution

Add @aftersave() event along with other events which can be subscribed to and unlike other events, they get broadcasted after the transaction is committed so that whatever happens inside @aftersave() doesn't affect the transaction.

@AfterUpdateCommit() can be added with similar behaviour for updates

Considered Alternatives

Alternate Options: I guess right now I can use this workaround or not use subscriber at all but they provide a clean approach which is why I am opening this feature request

Additional Context

No response

Relevant Database Driver(s)

  • aurora-mysql
  • aurora-postgres
  • better-sqlite3
  • cockroachdb
  • cordova
  • expo
  • mongodb
  • mysql
  • nativescript
  • oracle
  • postgres
  • react-native
  • sap
  • spanner
  • sqlite
  • sqlite-abstract
  • sqljs
  • sqlserver

Are you willing to resolve this issue by submitting a Pull Request?

No, I don’t have the time and I’m okay to wait for the community / maintainers to resolve this issue.

@falyoun
Copy link

falyoun commented May 10, 2024

I run into this issue a couple of times and so far, there is no "TypeORM" solution, however, I'd like to share how I am tackling it.
Instead of running actual logic -in your case blockchain transaction- inside the afterInsert/afterUpdate, I am creating a BullQueue, and inside afterInsert/afterUpdate I am pushing an event with some useful data like id, status, etc.., and pushing to a queue should almost never fail.
The queue will consume the events asynchronously, hence won't affect the current transaction.

A quick example

async afterInsert(event: InsertEvent<OrdersEntity>) {
    const { entity, manager } = event;

    const transactionOrder = await manager
      .createQueryBuilder(OrdersEntity, 'order')
      .leftJoinAndSelect('order.vendor', 'vendor')
      .leftJoinAndSelect('order.products', 'products')
      .where('order.id = :id', { id: entity.id })
      .getOne();

    const invalidateCachePromise = this.invalidateCache();
    // Pushing the event to BullQueue
    const snapshotPromise =
      this.ordersSnapshotsCapturerProducer.afterInsertHandler({
        order: transactionOrder,
      });
    await Promise.all([invalidateCachePromise, snapshotPromise]);
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants