Rollback vs. discard
So far, we have used "discard" as the alternative to "commit". If you or your program does not like modifications, the program simply skips the Commit()
and the changes to domain object data are not permanently stored in the persistence store. This is a consequence of data being stored in transactions. ClientTransaction.Current.Discard()
throws away the transaction; consequently, all object domain data therein is zapped into oblivion with it. This technique assumes that your program wants to give up the transaction together with the data, what is not always so. You can keep the transaction and loose the data with the Rollback()
method. ClientTransaction.Current.Rollback()
throws away modifications to domain objects in the client transaction, but not the transaction or the domain objects themselves. It simply reloads domain object data from the parent transaction (for sub-transactions}}) or the database (for root transactions) to restore its state since the last Commit()
. Here is another Dr. Freud example with a slightly modified EnterFreud() method.
In figure 1 we have committed "Sigmund Freud" (1.) to the domain object, as can be seen in the debugger (3.). We are about to change the FirstName to "Arnold":
In figure 2 we have written "Arnold" into Dr. Freud's FirstName (1.), what can be seen in the debugger (3.). We are about to roll that name change back (2.):
In figure 3 we Rollback() has done its thing (1.) and has restored Freud's FirstName (2.) by reloading the data that was committed before – "Sigmund":
Now let's see the contrast to Discard()
. In figure 3 above, we are about to discard the entire transaction. What will we get if discard the transaction and try to display Freud's first name with Console.WriteLine()
? (Next line.) The answer is this:
This is a very helpful exception. It tells you exactly what the problem is: "The transaction can no longer be used because it has been discarded."
Note that, in production code, you will not usually Discard()
client transactions. The scope will do that for you automatically. If you feel tempted to discard a client transaction, you should take stock of what you want to achieve, because it is more likely that you have a design problem in your code. (Just generic nitpicking, your mileage may vary.)