Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why TransactionScope timeout is defined in machine.config?

As we know from this answer, maxTimeout for TransactionScope is defined in machine.config.

So, what the reason? Why we can't override it in app.config (web.config) or just in code?

like image 909
Backs Avatar asked May 29 '17 11:05

Backs


1 Answers

Why TransactionScope timeout is defined in machine.config?

  • machine.config file store machine level configuration settings. Machine.config settings apply to all web applications which is residing on the server. and TransactionScope timeout value is something that anyone wants keep uniform across all your web applications.
  • An advantage of this would be when you want to change transaction-scope timeout value for all your application hosted in IIS, then you can do it by changing value in one single place. However, it doesn't mean that you can not override it in app.config or web.config file. There is a way to override it.

Why we can't override it in app.config (web.config) or just in code?

  • Few days ago, i was also looking for possible ways to override and i found below two solutions which worked for me. Here is link that contain complete article on this. Link

1. Override in web.config / app.config file : - in machine.config file, under "system.transactions" section-group node, in "machineSettings" section node, there is attribute named 'allowExeDefinition' with default value = "MachineOnly". Change this value to "MachineToApplication". This allows one to add the following to an application's web.config and override the machine wide setting :

<system.transactions>
<machineSettings maxTimeout="00:20:00" />
</system.transactions>
  • Although this approach changes a machine wide setting, it does not change the machine wide maxtimeout for the machine. One will be able to retain whatever value is set for the maxTimeout and one will be able to set whatever value is fit for the specific application in the app.config. Thus, each app can override the machine wide maxTimeout setting and set its own maxTimeout.

    2. Override in code :

  • This approach uses reflection API to accesses private data members of Microsoft classes. If you are not familiar with reflection API then you can refer to this Link
  • It doesn't require modifying the machine.config, it doesn't open up other application to possible DOS situations and it circumvents any company policy. Below is the code that does this:

    public static class TransactionManagerHelper
        {
            public static void OverrideMaximumTimeout(TimeSpan timeout)
            {
                //TransactionScope inherits a *maximum* timeout from Machine.config.  There's 
                  no way to override it from
                //code unless you use reflection.  Hence this code!
                //TransactionManager._cachedMaxTimeout
                var type = typeof(TransactionManager);
                var cachedMaxTimeout = type.GetField("_cachedMaxTimeout", 
                BindingFlags.NonPublic | BindingFlags.Static);
                cachedMaxTimeout.SetValue(null, true);
    
                //TransactionManager._maximumTimeout
                var maximumTimeout = type.GetField("_maximumTimeout", BindingFlags.NonPublic | BindingFlags.Static);
                maximumTimeout.SetValue(null, timeout);
            }
        }
    
  • To use it call the following before creating the TransactionScope object:

    TransactionManagerHelper.OverrideMaximumTimeout(TimeSpan.FromMinutes(5));

Path of Machine.config

  • 32-bit System

%windir%\Microsoft.NET\Framework[version]\config\machine.config

  • 64-bit System

%windir%\Microsoft.NET\Framework64[version]\config\machine.config

like image 68
Intimate Avatar answered Oct 01 '22 21:10

Intimate