The other day we got a bunch of these transaction exceptions logged on some of our production servers:
Exception: "The operation is not valid for the state of the transaction"
At first this exception was a bit cryptic, but when investigating it further is had this following inner exception:
InnerExceptionMessage: "Transaction Timeout"
It turns out that this was related to a client performing updates on 200.000 articles (!) and the executing transaction could no finalize within the default transaction timeout.
What is the default transaction timeout?
If you haven't configured this manually, the default transaction timeout is 1 minute, which I could confirm in our logs because our transaction completed successfully under 1 minutes but threw this exception every time it reached 1 minute (with heavy amount of data).
How do I increase the timeout?
What I ended up doing was increasing this transaction timeout just enough to be able to finalize such a huge amount of data for this specific client. This can be done on several levels, either in your code for each specific transaction, or application wide (web.config) or server wide (machine.config).
Where should I configure the timeout?
Where you do this depends on your setup, we ended up doing this application wide and not on the servers since this was a load balanced application, and we didn't want to have to configure this on each individual server. Also be careful in case you have several application on the same server because they will all share the machine.config timeout. We also didn't want to handle this on each individual transaction but rather a unified setting across the application that can be maintained on one place. But for educational purpose I will share all 3 options.
new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 10, 0))
<machineSettings maxTimeout=”00:10:00″ />