So how does a transaction work?
Now for a transaction, we need a so-called session.
We haven't worked with sessions before but a session basically means that all our requests are grouped
together logically you could say. You create a session and you store it in a constant let's say here, with
db getMongo,
this gives you access to the mongo server basically, start session,
now I have a session stored in there. Now that session again basically is just an object that now allows
me to group all requests that I send
based on that session together, that is how you can think about it.
Now you can use that session to start a transaction,
so start transaction is something you can do.
Now important, that session is required because technically every command I issue here is sent to the server
and then normally the server would forget me and therefore, we need that session so that when I send
something based on that session, the server remembers oh that session which behind the scenes is managed
through a session key and so on,
I know that one, that command you just sent me should be considered in the context of the other commands
you sent me based on that session,
that is how you can think about that.
So now we started the transaction,
we can now get access to a collection,
so let's say to users and products. So I'll create a new constant, usersC for collection and we use
that session again, get our database on which this session was created, get a database for that session now
or for this operation
and here the database is blog, that is the database I created earlier if you remember here, use blog
and then we get access to a collection,
the users collection
and get database definitely runs if you type it correctly.
And now I have that usersC so
let's name it
usersCol now.
Ok,
so now I got the users collection saved here with the right command.
Now let's repeat that for the posts call,
here we get access to the block database but now to the posts collection.
Ok so now we started a transaction and we got access to our collections,
now we can write all the commands we want to execute against these collections here.
So now first of all, what I'll quickly do without session is I'll execute
db users find pretty. Now important, since I don't run this against a session, this executes as normal and I get
my object ID and the object in general which I need,
so this is now not included in the transaction because it's not included in the session on which I started
the transaction,
I just needed to get the ID right now,
so now I can go back and use my usersCol which is this object which is basically a pointer at my collection
but also mapped to this session you could say.
So now I'm using the collection in the context of my session through that constant
and there, I can now use my normal operations inserting, finding, updating, that all works.
So here I can now basically run delete one, delete one and search for ID equal to objectID. If I now
hit enter, this was acknowledged and deleted but if I repeat db users find, you see the user still
is in the database,
so it hasn't been deleted yet,
it was just saved as a to-do
you could say. Now I will use my posts collection, so postsCol which I created here
and I will use that to then delete many items in there based on the userid which of course is that
same object id as I used for deleting the user.
Now this was also acknowledged and you say, it says deleted too but it didn't
yet write this to the database as I can prove by looking into my posts with db, not with the
session,
now you see the posts are still there. Because to really make this work or to really commit these changes
to the real database so to say, I have to run session commit transaction, there also would be abort transaction,
so in case you don't want to continue, you can abort it,
you should do that to cleanly close it though but now if you do that, the changes will not be applied
to the database, with commit
they will.
So if I run this, it failed initially,
now I repeated it without all these db in-between queries which seem to have messed it up.
If you just execute the steps basically as I explained them but now simply creating a session, then getting
access to your collections, then starting the transaction and then just specifying the two commands that
belong to the transaction and then committing it,
then it works
and now if I dive into my database and find my users, you'll see the user is gone, the one user ahead.
So this is how transactions work, you get access to a session, you then based on that session,
that's always important, you use that session to then store a reference to your collections in some variables
or constants
and you do that from your native drivers, for node and so on of course too, then you start a transaction
on the session and then you'd execute your manipulating queries. Finding doesn't make much sense in here
because well what would you find in there, in the transaction,
the transaction is all about safely changing data, like here
I delete the user, I delete the posts and then you commit the transaction.
You could also abort it with abort transaction
in case you don't want to continue
but if you want to continue,
well you can just commit it. Now
also important to understand here is that for this transaction, if it somehow would fail, if something
would go wrong,
let's say the user was deleted but the posts weren't, then it will roll back these operations in
commit transaction and thereafter your database will be in the same state as before.
So these actions either succeed together or they fail together,
that is the idea behind transactions.
Now you might remember this atomicity topic I talked about way earlier in the course. There I explained
that mongodb is atomic on a document level,
so if you write a document, it either is written entirely or not written at all.
This basically gives you atomicity across multiple operations, so across multiple steps or even something
like delete many. Normally each operation on its own would be guaranteed to work
but if you delete two posts here, you're not guaranteed that both deletes will work,
so with a session, you could even just wrap delete many or insert many to guarantee that either all documents are deleted
or inserted or none at all.
So you get atomicity on an operation level
so to say and not just on a document level. That is the idea behind transactions and that is a useful
feature for situations where you know that some operations depend on each other.
You should definitely not overuse it though, if you don't need it don't use it because obviously this
takes a bit more performance than a normal delete or insert,
so only use it if you know you need that cross operation consistency.