I'm trying to understand transactions in entity framework 6.. I searched a lot but I'm still confused..
Take a look at this:
Dim transaction = context.Database.BeginTransaction()
Using transaction
.
.
context.Entry(entity1).State = System.Data.EntityState.Added;
SaveChanges()
.
.
context.Entry(entity2).State = System.Data.EntityState.Added;
SaveChanges()
.
.
context.Entry(entity3).State = System.Data.EntityState.Added;
SaveChanges()
Transaction.Commit()
'Or Transaction.RollBack()
End using
Now what exactly does SaveChanges() Do? and how does it differ from the commit??
Does it begin a new (maybe internal) transaction for each insert and then commit it?
I read https://msdn.microsoft.com/en-us/data/dn456843.aspx.
..that was what I understood from "In all versions of Entity Framework, whenever you execute SaveChanges() to insert, update or delete on the database the framework will wrap that operation in a transaction. This transaction lasts only long enough to execute the operation and then completes. When you execute another such operation a new transaction is started."
My understanding is, all changes to the entities (especially where there are relationships that have cascaded deletes, or, reinsert an item that has been deleted) is to sort the operations so they are carried out in the correct order.
For example, if you have a table with a unique constraint, and you have deleted one entity with a unique value on the column with the constraint and reinserted another entity with the same value, the operations are carried out in the correct order so the underlying dmbs doesn't throw a unique constraint exception. The goes for non auto incremented primary keys and a variety of other things although hopefully you get the gist of it.
The entities are stored in a graph with the relationships as edges so it can sort the graph and perform the operations in the correct order.
This is carried out by the ChangeTracker. I know this from working with / building my own entity tracker using the source code from the awesome IQToolkit.
I also understand that this is carried out in a single transaction, if the underlying dmbs supports it...
Also, in your example, you only need to call
SaveChanges()
Once not after each time you change an entity.
You also don't need to create an explicit transaction and commit it, as SaveChanges does this internally, unless you need to rollback the transaction due to some external factor
EDIT
To explicitly answer your questions in bold:
"Now what exactly does SaveChanges() Do? and how does it differ from the commit??"
It sorts the sql commands generated by each change made to the entities and executes them, in a single transaction, in an order that will not violate any relationship or field constraints setup within the database. As it uses its own transaction, you don't need to wrap the operation in a new transaction and commit it, unless you have a reason to roll the operations back due to some external factor.
It differs from Commit as Commit will commit any changes made during a transaction, while SaveChanges creates it's own transaction around the updates and commits the transaction. What you are doing is nesting the transaction created by SaveChanges in the outer transaction, so you can cancel it if required.
"Does it begin a new (maybe internal) transaction for each insert and then commit it?"
No, it wraps them all and commits in a single, internal transaction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With