Django Transaction Atomicity

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello my name is xander welcome back to another django orm tutorial in this tutorial we take a first look at transaction atomicity this is going to be better served identifying a problem that we need to solve and then utilizing transaction atomicity to solve that problem so let's take a look at an example here i've mocked up a simple example of a bank application a user wants to transfer money from their bank account into someone else's bank account they want to make a payment to someone else so this application uh allows the user to type in their name the payer and then identify who they want to pay and then the amount of money that they want to pay them so behind the scenes we have a database here user a and user b those are current customers of the bank and they all have a balance of a hundred pound so you can imagine a user a wants to give um user b to pay um some money wants to pay them 10 pound so we submit that and then we have a look here and we can see that user b has now 10 pound more in their bank account and user a has 10 pound less so here behind the scenes we collect the information from the form clean it up and then we start to prepare some statements here to be executed on the database so first of all we collect the information about the payer the person paying and then we can go ahead and subtract the amount of money that they're paying from their balance their existing balance and then we save and of course then what we do is we collect the user's information that we want to pay or the person we want to pay the payee we collect their information and then we incrementally add the new amount that's being paid to their existing balance and save so nothing out of the ordinary let's just reset the balance of user a and b now if for example user a wanted to pay user c a hundred pound we know that user c doesn't exist user a does have a hundred pounds to pay so let's just go ahead and submit so we are presented with a problem which you might imagine because user c doesn't exist however if we go into the bank account details here and refresh you can see that user a the monies has been taken away from their balance this problem exists because if we look at the code you can see that django is executing this piece of code first which is updating the payer balance before it then adds the new balance to the payee so this is where the problem currently resides in the example so we can now introduce the idea that django's default behavior is to run in auto commit mode so that means that by default each query is immediately committed to the database so we have a problem it's the django's default behavior to run in auto commit mode user a's balance was reduced even if the payee does not exist so what's the solution let's think about database transactions as a workflow so what we had previously is transaction one that was updating the payer so we reduced their balance so that's the first thing that we performed and we committed that to the database so we saved that to the database that was transaction one and then django then looked at transaction two and that was to update the pay e so the person receiving the money so we updated their bank account so what we saw here in transaction two was a problem and that's where we returned a problem in our example so we didn't go ahead and commit t2 but if we look at this workflow here we can see that we've already committed um transaction one where we updated and reduced the balance of the payer so let's now think of a database transition as one or more sql operations that are treated as a unit so all operations should be executed successfully in order to call the transaction successful and this is the answer to our problem we now want to take those individual transactions as we had before and we want to treat them as a unit of transactions so we want to make sure that both of them are successful so both of our queries are successful in order for us to actually say that the transaction was successful for us to actually commit everything to the database so let's now think about our two queries as two transactions here we're going to perform the first query and make a save point so the point of that is that if there is a problem with the preceding query then what we can do because we've made a save point we know what we did previously so we can kind of roll back the update so here for example we can perform this action of updating the customer payer data so the balance we remove the the amount from their bank account we make a save point we know what we're going to do everything is okay at this point but it's not being fully committed yet then we move over to the second query and then we try and perform this now if this is committed and everything is okay it means that everything will be saved and now that is one transaction so once everything is successful all the queries are successful and no errors have occurred then we could say that this transaction is now successful everything has been saved all the queries have been performed now if one or of these queries were to fail it would mean that we roll back everything none of these queries would get committed to the database so we can say that a transaction is a sequence of one or more sql operations that are treated as a unit all operations should be executed successfully in order to call the transaction successful and we've seen that there's mechanisms in place so that if a query or operation does fail we can roll back utilizing save points for example so this idea of transactions has a lot of different theory one of them being acid properties so transactions ideally have four properties commonly known as acid so these are just sand standard sets of properties aimed to guarantee database transactions are processed reliably so the top one here atomicity it means that you guarantee that either all of the transaction succeeds or none of it does so we want to make sure thinking about our atomicity principle here we want to make sure that this all happens or none at all so let's just now put that into context here in django and actually ask django to perform this type of operation so we now want to tell django that we want this to this transaction to be atomic we want to run these as a unit these two queries as a unit so let's go ahead and let's from django db import transaction so we can flag or tag queries statements functions um for atomic transactions in two ways we first of all have the declarator here transaction dot atomic so if i would apply this it's implying that any of these queries here um they should all be applied as a unit so if one of them fails it should roll back and not apply any of these changes so we can also apply this as a context manager so with transaction.atomic and then we identify the queries that we want to run so let's just apply this now to our situation again right so going back to our example uh let's just uh update the monies right so they both have a hundred so let's go back and try this again so i'll just refresh user a and use a b so let's just go for 50 just make sure it's working okay still okay so that works so let's just try user a and user c again for example so c does not exist let's just go for 50 i press submit so we are still receiving the error message but let's go back and refresh and you can now see that because we're running the queries as a unit user's a's balance does not get changed so here we can say now that we've applied or we've considered atomicity with in our application we've guaranteed now that either or the transactions succeed or none of them does now if we look through the other acid principles here consistency this ensures that you guarantee that all data will be consistent isolated guarantees that all transactions will occur in isolation so no transaction will be affected by any other transaction well this is an interesting point so the question here is that how can we ensure that no transaction will be affected by any other transaction just take this example our database has user a a balance of a hundred imagine we had three or a thousand requests all coming into our database at exactly the same time trying to update the balance of user a potentially what might happen is that request here might capture the current instance of a hundred and it might plus a hundred but the same time request here might do the same thing so what you end up with is potentially errors in the actual balanced data because we're trying to perform concurrent operations on a different set of data this was a good excuse to point you towards the django documentation and have a read through the query set api reference so eventually you'll get down to select for update and this is what i wanted to point out here so select for update allows us to return a query set that will lock rows until the end of the transaction so essentially here when we want to perform a request on some data in the database we can lock it in so that we can perform the operation and no other operation can be performed on that data so going back to our example here request one would lock in this information perform the request and then the second request could then perform an operation on the actual data at that point of time so by doing so we are moving towards this idea of isolated so no transaction will be affected by any other transaction so we can apply the select for update in our application very simply so i've removed the collecting the customer from the transaction atomic here and i've select utilizes a select for update so we get the actual user and then we then perform our operations and of course these operations must be committed as a unit so they are wrapped with our transaction atomic so in short atomic or atomicity is the defining property of a database transaction so here we utilize atomic to create a block of code within which the atomicity of our database is guaranteed we saw that we can apply this very simply as a declarator or using context manager within our code and there we go that's a first look at transaction atomicity so i do hope that was useful not the most cohesive presentation but hopefully i've got the main points over to you and now you can have a look at through some of that documentation that i mentioned as well as reading further into the subject so as for normal i thank you very much for listening and i do hope to see you in the next tutorial
Info
Channel: Very Academy
Views: 5,103
Rating: undefined out of 5
Keywords: django transaction atomicity, django atomic, django atomic transactions, django, python, django tutorial, djangotutorial, django tut, django 3, django examples, learn django, django beginners, beginners django, django framework, django example, django 2021, python django
Id: BchP5Mn1IYg
Channel Id: undefined
Length: 12min 56sec (776 seconds)
Published: Mon May 17 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.