Playing Next Lesson In
seconds

Transcript

  1. (upbeat music) So for our profiles update here, let's say that we only ever want the profile

  2. and description to update whenever both of these saves actually happen successfully. For example, at present, if we were to invalidate our profiles update

  3. by doing something like profile.userid and setting that to some user that does not exist inside of our database, this save call will then result in an error

  4. because it won't be able to find a user thanks to our foreign key constraint with whatever this ID is here. If we give that a save, jump back into our browser

  5. and let's switch our John Doe edit to John Doe edit two and let's switch our biography to John Doe edit two to match the name and hit update here. We do indeed get our error as expected

  6. because of our foreign key constraint, but now if we go back into our profile edit page, so if we go back and refresh just to make sure that we have the latest data, you'll see that things actually updated despite us running into an error,

  7. meaning that not all of our operations completed successfully. And that's where transactions come into play. A transaction is essentially going to keep track of the changes that we're making

  8. and provide us a way to either commit them fully to the database long-term or roll them back to undo them. So first, what we're gonna wanna do

  9. is from everything up through our profile down through our save changes, let's wrap this inside of a try catch. Oh, so try catch just like so

  10. and paste our profile query along with our saves inside of there. Then let's go ahead and create a transaction. So do const TRX, short for transaction

  11. equals await import our DB from AdonisJS Lucid Services DB and call dot transaction. This will return back a new instance of a transaction for us,

  12. which contains a commit and rollback method doing exactly what we described earlier. So if everything completed successfully and we run through all of our calls that we have here,

  13. we'll want to await TRX and commit those changes to our database. If we run into an error at any point in time,

  14. we'll want to await TRX dot roll back those changes to undo them rather than committing. The next thing that we need to do

  15. is actually bind this transaction to these calls. And since all of our calls here actually go through our user, we'll want to bind that directly to our user.

  16. So we can do off user exclamation point to assert it. And there's a method called use transaction that we can call and pass in the transaction

  17. that we want our user model to use. And this cascades through as we query things with our relationships. So for example, inside of our profile service

  18. with our find call, we're using our user model's relationship to actually query out the profile, meaning that the returned profile

  19. will then be attached to that same transaction as well. If you don't have that system, what you could always do is just use transaction

  20. on the profile, just the same as we are with our user here. Since we do have that cascading through our relationship, though, we don't need to worry about that in this particular use case. You can also pass transactions

  21. through to other calls as well. So for example, if we were doing a wait, I'm going to go ahead and just import our profile model here temporarily and call create. We'll pass in our data.

  22. The second argument is where we can pass in a client, which is a transaction client. So we could create with a transaction just like so.

  23. And a lot of these static methods work the exact same way where you have query options as the second argument where you can pass in a client for your actual transaction. Okay, let's go back a couple of steps

  24. and let's give this a run. So first let's go ahead and put our error back. So profile.userid equals some ID that definitely doesn't exist inside of our database. Let's go and jump back into our browser

  25. and let's try to switch this to a three. Let's update our profile. And you'll see that we ran into an error, but since we're now catching that error, we just get returned back here,

  26. which is what we're specifying to do at the end of our handler. So that's expected behavior. But in addition to that, you also see that our three change did not persist

  27. in either of these two contexts. Additionally, it looks like Firefox was holding on to the edit two value from our biography there from our initial error. Cool, let's do a hard refresh

  28. just to make sure it's not holding on to anything else. There we go, okay, cool. So let's try that once more. Three there, three there, update. And you'll see it goes right back to how it was prior to that change,

  29. because neither of those two changes are actually saving into the database now because our transaction is being rolled back due to this foreign key constraint error.

  30. If we remove that error, jump back into our browser, and now we try to switch these to three, give that an update, you'll see everything goes through A-okay. Give this a refresh.

  31. Everything still works A-okay. It'd probably be good to go ahead and display some form of an error whenever this does actually happen. So let's go ahead and grab our session,

  32. scroll back down, and we can do session.lash, and we can flash something into our errors bag and call that maybe something like form

  33. with a message of something went wrong, or whatever you'd like there for the message. Give that a save, and then we'll jump back into our edit page. And actually, let's jump back into our login page

  34. and grab this error right here. Jump back into our edit page now, paste it in above our inputs. And instead of looking for E invalid credentials,

  35. we're just gonna be looking for a form error. Our message will remain the same. Give that a save. And actually, before we test that out, we do need to add our error back in.

  36. So profile.userID equals some non-existent ID there. And now let's test it out. So switch those to four, update, and there we go.

  37. So now we get something went wrong whenever something actually goes wrong, and our transaction gets rolled back.

Saving All Or Nothing with Database Transactions

In This Lesson

We'll learn about database transactions and how we can use them to batch commit or rollback updates, safeguarding against partial updates due to errors.

Created by
@tomgobich
Published

🕰️ Chapters
00:00 - Demoing Why You'd Use A Transaction
00:51 - What Is A Database Transaction?
01:08 - Creating A Database Transaction
02:00 - Binding Our Transaction To Our Database Operations
03:14 - Demoing A Transaction In Action
04:22 - Displaying An Error On Transaction Rollback

Join the Discussion 0 comments

Create a free account to join in on the discussion
robot comment bubble

Be the first to comment!