1 00:00:00,150 --> 00:00:09,480 ‫Hey, guys, what's up and this video I want to talk about, how can you build an online booking system 2 00:00:10,350 --> 00:00:17,880 ‫and not just the actual act of building an online booking system, but the most important feature, 3 00:00:17,880 --> 00:00:26,730 ‫which is prevent double booking or prevent race condition when two people try to book the same seat 4 00:00:26,730 --> 00:00:29,820 ‫at the same exact millisecond? 5 00:00:29,950 --> 00:00:36,210 ‫OK, I've seen a lot of systems that actually don't have this problem solved. 6 00:00:36,210 --> 00:00:36,600 ‫Right. 7 00:00:36,620 --> 00:00:37,740 ‫So I'm going to talk about it. 8 00:00:37,740 --> 00:00:42,360 ‫I'm going to talk about how to prevent this condition, can talk about exclusive locks, ride. 9 00:00:42,900 --> 00:00:48,960 ‫And I'm not going to show you how I built this application because it's very straightforward, not really 10 00:00:48,960 --> 00:00:49,470 ‫magic. 11 00:00:49,470 --> 00:00:54,230 ‫I might I might make another video to actually show you how the how I built the application from scratch. 12 00:00:54,240 --> 00:00:56,220 ‫It's it's it's really straightforward. 13 00:00:56,220 --> 00:00:59,040 ‫I'm using Express, Norges and Postgres as the back. 14 00:00:59,220 --> 00:01:02,090 ‫I'm going to go through the application right now. 15 00:01:02,730 --> 00:01:07,950 ‫The idea here as we are building an online system that books, I don't know, seats. 16 00:01:07,950 --> 00:01:08,310 ‫Right. 17 00:01:08,640 --> 00:01:11,340 ‫You're you're buying tickets at a concert. 18 00:01:11,610 --> 00:01:16,320 ‫And this is one user and this is just another instance, maybe another user. 19 00:01:16,320 --> 00:01:16,680 ‫Right. 20 00:01:16,680 --> 00:01:17,730 ‫And trying to open that. 21 00:01:17,730 --> 00:01:18,780 ‫And these are seats. 22 00:01:18,780 --> 00:01:19,690 ‫Seats are green. 23 00:01:19,710 --> 00:01:21,240 ‫I mean, they are available. 24 00:01:21,540 --> 00:01:23,130 ‫Red are booked. 25 00:01:23,310 --> 00:01:26,910 ‫OK, how about we actually try to implement this thing? 26 00:01:26,910 --> 00:01:35,550 ‫So if I click on this seat number three and I say, hey, my name is Ali, I know in a book this seat, 27 00:01:35,940 --> 00:01:39,530 ‫I'm going to get back a message, say, hey, this was booked successfully. 28 00:01:39,870 --> 00:01:40,100 ‫Right. 29 00:01:40,170 --> 00:01:41,550 ‫And we're going to go through the logic. 30 00:01:41,550 --> 00:01:43,800 ‫And now what what exactly am I doing here? 31 00:01:44,070 --> 00:01:48,960 ‫And if I do this and I'm going to fresh here, I can see that this now is booked by Ali. 32 00:01:48,960 --> 00:01:50,490 ‫You can see there is a tooltip here. 33 00:01:50,670 --> 00:01:52,950 ‫I didn't I really it's a bad front. 34 00:01:52,950 --> 00:01:55,340 ‫And I know it's just does the trick. 35 00:01:55,350 --> 00:02:01,510 ‫And if I go to the other using a refresh, you can see that this has taken effect or so of that user 36 00:02:01,510 --> 00:02:06,120 ‫like, say, book jack, book number nine. 37 00:02:06,450 --> 00:02:13,320 ‫And you can see that I am now actually debugging this and I'm going to show you exactly what happened. 38 00:02:13,320 --> 00:02:16,980 ‫So how about we go through the code and I made a put request here. 39 00:02:17,520 --> 00:02:23,100 ‫And what we're doing here is we get the ID, which is the seat ID and the name from the prompt. 40 00:02:23,310 --> 00:02:25,860 ‫And I am connecting through a Posterous pool. 41 00:02:25,890 --> 00:02:28,920 ‫So I get to pick up one client from the pool. 42 00:02:29,160 --> 00:02:34,800 ‫And we talked about Norges Postgrads and how we actually make transactions. 43 00:02:34,800 --> 00:02:36,030 ‫I'm going to reference the videos here. 44 00:02:36,030 --> 00:02:39,360 ‫If you want details this, I'm going to go quickly through them. 45 00:02:39,660 --> 00:02:42,990 ‫I'm going to begin a transaction because obviously this is a transaction. 46 00:02:42,990 --> 00:02:43,230 ‫Right? 47 00:02:43,440 --> 00:02:45,990 ‫And the first thing we're going to do in the transaction is this. 48 00:02:46,230 --> 00:02:48,420 ‫I'm going to select Star from Seeds. 49 00:02:49,000 --> 00:02:56,520 ‫I need to actually query this seat and see if it's actually booked or not. 50 00:02:57,270 --> 00:02:57,990 ‫That makes sense. 51 00:02:57,990 --> 00:02:58,200 ‫Right. 52 00:02:58,200 --> 00:02:59,820 ‫A lot of booking system actually does that. 53 00:03:00,000 --> 00:03:03,420 ‫And so where ID is a good one and is booked equals zero. 54 00:03:03,420 --> 00:03:04,980 ‫That means it's not it's not booked. 55 00:03:05,400 --> 00:03:06,300 ‫And that's perfect. 56 00:03:06,300 --> 00:03:09,480 ‫When I do this query, I'm going to get the result back. 57 00:03:09,480 --> 00:03:16,020 ‫And the real count is one that means, hey, you actually found this seat and it's available for you. 58 00:03:16,880 --> 00:03:17,280 ‫All right. 59 00:03:17,280 --> 00:03:18,780 ‫So far, so good. 60 00:03:19,380 --> 00:03:23,040 ‫But if that seat is not available, you're going to get an error. 61 00:03:23,040 --> 00:03:25,140 ‫We're going to send back in our seats already booked. 62 00:03:25,290 --> 00:03:28,950 ‫This is to avoid this double booking. 63 00:03:28,980 --> 00:03:32,640 ‫But we're going to show that this is not enough in a minute. 64 00:03:32,730 --> 00:03:33,070 ‫Right. 65 00:03:33,450 --> 00:03:34,860 ‫A lot of people actually do this. 66 00:03:34,860 --> 00:03:36,690 ‫This party, Aquarian, check that thing. 67 00:03:36,690 --> 00:03:37,830 ‫But this is not enough. 68 00:03:38,070 --> 00:03:44,010 ‫So I'm going to go and once we actually pass this, that we are safe to actually execute an updated 69 00:03:44,010 --> 00:03:51,450 ‫statement and said to the go away, please, is his book the equal one and the name equal, then where 70 00:03:51,500 --> 00:03:52,320 ‫it equal to one? 71 00:03:52,320 --> 00:03:55,020 ‫We just physically set that statement. 72 00:03:55,470 --> 00:03:59,970 ‫So let's go ahead and just run this thing and we commit the transaction. 73 00:03:59,970 --> 00:04:02,190 ‫We release the client back to the pool. 74 00:04:02,280 --> 00:04:02,450 ‫Right. 75 00:04:02,490 --> 00:04:05,190 ‫And then we send the result till we get back. 76 00:04:05,190 --> 00:04:07,740 ‫We get back also here booked successfully. 77 00:04:07,860 --> 00:04:08,130 ‫Right. 78 00:04:08,520 --> 00:04:10,080 ‫And then if for a year. 79 00:04:10,230 --> 00:04:10,710 ‫Right. 80 00:04:11,250 --> 00:04:18,540 ‫And I'm not going to refresh actually, if I actually click this nine now and I'm going to book it for 81 00:04:18,540 --> 00:04:20,100 ‫which is already book, we know that it's book. 82 00:04:20,100 --> 00:04:20,430 ‫Right. 83 00:04:20,760 --> 00:04:26,250 ‫If I say I don't know, saying that, OK, we get an error failed. 84 00:04:26,640 --> 00:04:33,090 ‫Couldn't book because it's already booked and the reason is because we have queried and that Kuwait 85 00:04:33,090 --> 00:04:34,170 ‫actually failed. 86 00:04:34,170 --> 00:04:34,740 ‫Returned. 87 00:04:34,740 --> 00:04:36,780 ‫There's no record on gonorrhea. 88 00:04:37,500 --> 00:04:44,250 ‫All right, Hosain, what are you doing that all of the stuff, y'know, here is the floor of this design. 89 00:04:44,490 --> 00:04:46,650 ‫The problem with this design is. 90 00:04:47,940 --> 00:04:57,390 ‫Double booking can easily happen, not on my single machine, obviously, but if you have a flux of 91 00:04:57,390 --> 00:05:04,680 ‫requests coming at the same time, you will get into a situation where both statements actually at the 92 00:05:04,680 --> 00:05:07,620 ‫same time you can imagine them executing impera. 93 00:05:07,710 --> 00:05:09,720 ‫They query the seat is available right. 94 00:05:10,320 --> 00:05:15,360 ‫The first transaction query and says, oh, the seat is available and it reaches here. 95 00:05:15,630 --> 00:05:21,360 ‫And the second query also queries and also finds out that the seat, the same seat is also available. 96 00:05:21,480 --> 00:05:21,670 ‫Right. 97 00:05:21,810 --> 00:05:25,410 ‫So both of them will succeed on this if statement. 98 00:05:25,410 --> 00:05:29,310 ‫They will pass it and both of them will execute the update. 99 00:05:29,430 --> 00:05:32,010 ‫And that's the problem in this case last to an end. 100 00:05:32,340 --> 00:05:39,240 ‫But incorrectly, that client will get the message that actually your booking has been succeed. 101 00:05:39,240 --> 00:05:46,670 ‫And we saw a lot of back back maybe 10 years ago when online cinema became a thing. 102 00:05:46,680 --> 00:05:47,060 ‫Right. 103 00:05:47,070 --> 00:05:51,960 ‫We always get double booking because of this problem, because it's a popular system. 104 00:05:51,960 --> 00:05:52,180 ‫Right. 105 00:05:52,200 --> 00:05:53,810 ‫A lot of people quit at the same time. 106 00:05:53,910 --> 00:05:55,290 ‫So we're going to show how to fix that. 107 00:05:55,360 --> 00:05:56,910 ‫First of all, let's reproduce this. 108 00:05:56,910 --> 00:06:02,520 ‫Let's show you actually this is going to happen, but I'm going to do this with the power of debugging 109 00:06:03,150 --> 00:06:03,870 ‫is what I'm going to do. 110 00:06:04,500 --> 00:06:14,190 ‫I am going to book I'm going to book seat number 15 now, and I am going to sign him to wreck. 111 00:06:14,280 --> 00:06:14,820 ‫All right. 112 00:06:15,570 --> 00:06:21,270 ‫And this will essentially go to the debugging statement, passes all of that stuff. 113 00:06:21,540 --> 00:06:23,160 ‫And I'm going to post that here. 114 00:06:23,160 --> 00:06:28,380 ‫I'm going to intentionally not resume the code to go to continue. 115 00:06:28,380 --> 00:06:29,970 ‫But guess what? 116 00:06:29,970 --> 00:06:38,020 ‫It actually passed the select statement that actually checks whether whether the it exists or not. 117 00:06:38,310 --> 00:06:41,840 ‫So the seat is available. 118 00:06:42,270 --> 00:06:43,200 ‫Here's what I'm going to do. 119 00:06:44,790 --> 00:06:46,110 ‫The seat is available. 120 00:06:46,110 --> 00:06:48,690 ‫But that guy did an updated. 121 00:06:48,690 --> 00:06:54,090 ‫Yet Rick did not actually reserve the seat because he didn't reach the statement. 122 00:06:54,090 --> 00:06:54,360 ‫Right. 123 00:06:55,440 --> 00:07:05,880 ‫Now, if I go to the other client and I also try to book this guy and I say, Edmund, want to book 124 00:07:05,880 --> 00:07:07,830 ‫this guy this, I don't have a debugger. 125 00:07:08,070 --> 00:07:11,430 ‫This guy will completely succeed because there's no debugging. 126 00:07:11,430 --> 00:07:11,650 ‫Right. 127 00:07:11,880 --> 00:07:17,840 ‫We'll find out this is available and it will actually commit the transaction or this is book. 128 00:07:17,850 --> 00:07:19,680 ‫Now, here's what I do now. 129 00:07:19,680 --> 00:07:22,590 ‫I'm going to just release the code, go ahead and continue. 130 00:07:23,220 --> 00:07:29,310 ‫And you can see that both of them actually booked the same seat. 131 00:07:29,310 --> 00:07:30,600 ‫And that's the problem. 132 00:07:30,610 --> 00:07:34,770 ‫This is what it's called, race condition in online system or double booking. 133 00:07:34,890 --> 00:07:42,480 ‫And here is how we can fix this problem, guys, using the concept of exclusive locks, how about we 134 00:07:42,480 --> 00:07:43,580 ‫jump into it and fix it? 135 00:07:44,580 --> 00:07:46,740 ‫The problem here, guys, is. 136 00:07:48,830 --> 00:07:53,490 ‫Both of these guys are attempting to edit the same row technically, right? 137 00:07:53,990 --> 00:07:57,650 ‫So the solution, one solution at least as. 138 00:07:58,890 --> 00:08:13,140 ‫The first person or process to get to the role should obtain an exclusive lock on that row so that the 139 00:08:13,140 --> 00:08:20,670 ‫other process, when it tries to execute it, it will have to wait until the other transaction actually 140 00:08:20,670 --> 00:08:21,340 ‫completed. 141 00:08:21,510 --> 00:08:23,260 ‫And how do we do this in postgrads? 142 00:08:23,490 --> 00:08:24,600 ‫It is very simple. 143 00:08:24,840 --> 00:08:28,030 ‫The same thing you select that you're selecting this role, right. 144 00:08:28,860 --> 00:08:32,900 ‫The only thing you need to do is add two things at the end. 145 00:08:32,910 --> 00:08:36,630 ‫So for update, that's it. 146 00:08:36,870 --> 00:08:41,020 ‫When you do select star from Select where ID and you query that role. 147 00:08:41,400 --> 00:08:47,320 ‫You also say for update and that is a call, the role level luck and few databases actually support 148 00:08:47,320 --> 00:08:47,440 ‫that. 149 00:08:47,460 --> 00:08:48,540 ‫Not all databases. 150 00:08:48,540 --> 00:08:48,740 ‫Right. 151 00:08:49,020 --> 00:08:53,070 ‫So this is a very important feature in some databases, I suppose. 152 00:08:53,160 --> 00:08:54,630 ‫I think MySQL also supported. 153 00:08:55,200 --> 00:08:56,490 ‫Oracle definitely supported. 154 00:08:56,670 --> 00:08:57,990 ‫And you do it for update. 155 00:08:58,180 --> 00:09:01,820 ‫And the syntax 692 is almost identical in all of them. 156 00:09:02,100 --> 00:09:04,500 ‫So you do select staff for updates. 157 00:09:05,010 --> 00:09:06,020 ‫Wow. 158 00:09:06,030 --> 00:09:06,410 ‫All right. 159 00:09:06,480 --> 00:09:11,080 ‫The moment you do that, the database will have an exclusive lock on that role. 160 00:09:11,400 --> 00:09:19,800 ‫That means if someone tries to update that rule or selected for update as well, they will have to wait. 161 00:09:20,490 --> 00:09:28,650 ‫And this is what I don't like about progress in Oracle, because I use Oracle for 15 years and an oracle. 162 00:09:28,650 --> 00:09:30,180 ‫That's why Oracle is expensive. 163 00:09:30,300 --> 00:09:37,560 ‫One of the reasons, as in Oracle, you can actually specify a time out here, says, hey, wait four 164 00:09:37,560 --> 00:09:42,900 ‫or five seconds right here is actually an indefinite wait. 165 00:09:42,990 --> 00:09:44,790 ‫I'm going to show that now in a minute. 166 00:09:45,450 --> 00:09:45,810 ‫All right. 167 00:09:46,050 --> 00:09:51,870 ‫So let's go ahead and try to do now that we have fixed that, let's refresh this thing and let's also 168 00:09:52,080 --> 00:09:57,840 ‫rerun our my second application right on board, eight, eight, eight, eight. 169 00:09:58,320 --> 00:10:00,960 ‫And let's check this up. 170 00:10:01,170 --> 00:10:01,520 ‫Right. 171 00:10:02,310 --> 00:10:06,060 ‫And for fun, let's just clear all that box. 172 00:10:06,060 --> 00:10:06,390 ‫Right. 173 00:10:06,390 --> 00:10:08,610 ‫I'm going to update Sytek will push back. 174 00:10:09,300 --> 00:10:11,060 ‫What a double this. 175 00:10:11,080 --> 00:10:14,390 ‫No, no one is looking at anything just like that. 176 00:10:14,880 --> 00:10:15,390 ‫All right. 177 00:10:15,480 --> 00:10:17,250 ‫Everything is now unbooked. 178 00:10:17,610 --> 00:10:18,300 ‫Sweet guys. 179 00:10:18,300 --> 00:10:19,830 ‫All right, here's what I'm going to do. 180 00:10:20,550 --> 00:10:21,480 ‫I'm going to do the same thing. 181 00:10:21,600 --> 00:10:23,010 ‫Going to book seat fifteen. 182 00:10:23,310 --> 00:10:27,300 ‫I'm going to one, for example, booking seats fifteen. 183 00:10:27,690 --> 00:10:30,840 ‫We go there, hopefully the debugger anytime soon now. 184 00:10:30,840 --> 00:10:35,340 ‫OK, we selected the same stadium, but now it's for update. 185 00:10:35,340 --> 00:10:37,230 ‫There is a little bit of difference in the database. 186 00:10:37,230 --> 00:10:39,090 ‫It's freaking out now, right? 187 00:10:39,120 --> 00:10:40,080 ‫We got it now. 188 00:10:40,960 --> 00:10:41,710 ‫Here's the thing. 189 00:10:43,590 --> 00:10:47,640 ‫This guy will always be the winner no matter what, I'm going to find out how. 190 00:10:47,940 --> 00:10:51,090 ‫So the other process now will try to book 15. 191 00:10:51,090 --> 00:10:51,710 ‫Was it 15? 192 00:10:51,720 --> 00:10:52,590 ‫I think it's 15. 193 00:10:52,620 --> 00:10:54,890 ‫Let's just make sure I think it's 15. 194 00:10:55,620 --> 00:10:57,180 ‫Yep, 15 or so. 195 00:10:57,180 --> 00:10:57,570 ‫15. 196 00:10:57,570 --> 00:11:04,820 ‫If I click 15 and I say, Melissa, I want to book 15 is what we're going to do. 197 00:11:06,220 --> 00:11:08,760 ‫Look at that, we didn't receive anything is just waiting. 198 00:11:10,320 --> 00:11:16,560 ‫Now, the process is just stock ride and this is what I don't like, how our policy there is no option. 199 00:11:16,830 --> 00:11:17,420 ‫Am I wrong? 200 00:11:18,080 --> 00:11:19,020 ‫Correct me if I'm wrong. 201 00:11:19,350 --> 00:11:25,940 ‫There is no option to actually give up and time out after after a certain amount of waiting. 202 00:11:25,950 --> 00:11:26,250 ‫Right. 203 00:11:26,790 --> 00:11:29,300 ‫So this guy is waiting and this is a bad user experience. 204 00:11:29,310 --> 00:11:31,020 ‫That's the limitation of this now. 205 00:11:31,320 --> 00:11:33,720 ‫And this is where your database actually shines. 206 00:11:34,140 --> 00:11:41,910 ‫Now, if I go and say, release that cracken here, go back this guy. 207 00:11:42,890 --> 00:11:43,640 ‫This is what happened. 208 00:11:44,450 --> 00:11:49,670 ‫Something happened in your right book successfully is the guy who actually the person who actually made 209 00:11:49,670 --> 00:11:56,270 ‫that transaction book successfully, but this guy was waiting technically right here. 210 00:11:56,280 --> 00:11:57,290 ‫They were stuck. 211 00:11:57,590 --> 00:12:09,170 ‫And the moment this process actually released the transaction, what happened is that Locke got unblocked 212 00:12:09,170 --> 00:12:15,500 ‫and now we selected the brand new committed change, which was what it was actually committed, which 213 00:12:15,500 --> 00:12:17,660 ‫was the rate is already booked. 214 00:12:17,690 --> 00:12:19,090 ‫I mean, this result is zero. 215 00:12:19,100 --> 00:12:20,820 ‫That means this either already booked. 216 00:12:21,050 --> 00:12:21,370 ‫All right. 217 00:12:21,590 --> 00:12:23,810 ‫And that's what happened, essentially, guys. 218 00:12:23,820 --> 00:12:34,460 ‫So this is now a bulletproof online booking system that is essentially race safe or or you cannot get 219 00:12:34,610 --> 00:12:37,730 ‫double booking with them, obviously comes with a price. 220 00:12:38,480 --> 00:12:43,850 ‫But that price, remember, nobody in their right mind will put a debugger, obviously, and this will 221 00:12:43,850 --> 00:12:45,400 ‫take a finite amount of time. 222 00:12:45,410 --> 00:12:47,440 ‫Milliseconds is very fast. 223 00:12:47,450 --> 00:12:50,990 ‫So the wait will almost be unnoticeable. 224 00:12:51,170 --> 00:12:51,480 ‫Right. 225 00:12:51,770 --> 00:12:55,160 ‫So that's only a good encoding book already booked, right. 226 00:12:55,400 --> 00:12:58,010 ‫All right, guys, that was a short video talking about this. 227 00:12:58,010 --> 00:13:03,080 ‫Let me know, guys, if you actually want me to build this application from Scott showing you how to 228 00:13:03,290 --> 00:13:08,270 ‫highlight what all the species we explained all that stuff before everything. 229 00:13:08,300 --> 00:13:08,650 ‫Right. 230 00:13:08,810 --> 00:13:09,710 ‫That gate requires. 231 00:13:09,740 --> 00:13:12,200 ‫This is a port also for fun. 232 00:13:12,200 --> 00:13:18,010 ‫I added a delete message to move it, to delete that booking, to unblock that thing. 233 00:13:18,020 --> 00:13:23,000 ‫And obviously, this is a very simple I'm going to reference the source code below for you guys if you're 234 00:13:23,000 --> 00:13:23,630 ‫interested. 235 00:13:24,350 --> 00:13:29,840 ‫And the database also, it's just a Bosco's on Docker, very straightforward. 236 00:13:30,200 --> 00:13:34,560 ‫And all the tutorials, all this post Christodoulos, we have done them before. 237 00:13:34,580 --> 00:13:36,740 ‫Let me know if you have any questions. 238 00:13:36,890 --> 00:13:38,390 ‫Let me know if I missed anything. 239 00:13:38,390 --> 00:13:39,940 ‫I'm going to see you on the next one. 240 00:13:40,430 --> 00:13:42,170 ‫You guys stay awesome.