Transactions have two events we can bind handlers to.
Commit - when the transaction persists its changes to the database
Rollback - when the transaction reverts any changes applied to the database
Snippet Scenario
Let's say we have a Notification model. When new notification records are created we want to emit an event to send an email to the notification recipient.
However, our notification is created inside a transaction that's in charge of persisting other records besides our notification.
In case we run into any errors between our notification creation and our transaction commit, we'll only want to emit our event that sends the email when we know our transaction completes and our records are all persisted.
// inside a controller or service const notification = new Notification() if (trx) { notification.useTransaction(trx) } notification.merge({ userId: post.author.id, initiatorUserId: user?.id, notificationTypeId: NotificationTypes.COMMENT, table: Comment.table, tableId: comment.id, title: `${user.username} commented on your post`, body: UtilityService.truncate(comment.body), href: this.getGoPath(comment) }) await notification.save() await notification.trySendEmail(post.author.id, trx) // 👈 we'll dig into this // ... other actions await trx?.commit()
Copied!
Here we're creating our notification record, which may or may not utilize a transaction.
export default class Notification extends BaseModel { // ... other stuff public async trySendEmail( userId: number, trx: TransactionClientContract | undefined | null = undefined ) { const user = await User.query() .where({ id: userId }) .preload('profile') .firstOrFail() // user doesn't want notified, skip send if (!this.isEmailEnabled(user.profile)) { return } // no transaction, go ahead and send then exit if (!trx) { return Event.emit('notification:send', { notification: this, user }) } // otherwise, wait for transaction to commit, then send trx.on('commit', () => { Event.emit('notification:send', { notification: this, user }) }) } }
Copied!
- app
- Models
- Notification.ts
Join The Discussion! (0 Comments)
Please sign in or sign up for free to join in on the dicussion.
Be the first to Comment!