7

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?

Backs
  • 24,430
  • 5
  • 58
  • 85
  • Addition to this question, i have one more doubt - if i define this in web.config, do it overwrite machine.config? – Chandan Kumar May 29 '17 at 11:09
  • @uɐpuɐɥƆ I think what you are looking for is explained in the linked thread in [this answer](https://stackoverflow.com/a/12941902/238902) – default May 29 '17 at 11:13
  • @uɐpuɐɥƆ you can't add it. Project will not load this configuration – Backs May 29 '17 at 11:16
  • 1
    `maxTimeout` limit needs to be a machine-level setting, not an application-level setting, because transaction scope can regulate transactions between applications. If two applications provide different setting for `maxTimeout`, there would be a confusion as to which limit should be used. – Sergey Kalinichenko May 29 '17 at 11:21
  • @dasblinkenlight what about distributed transactions when 2 servers communicates? – Backs May 29 '17 at 11:31

1 Answers1

4

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

Intimate
  • 446
  • 2
  • 5
  • 18
  • Hi, yes, I use solution with reflection. Thank for full answer – Backs Dec 24 '18 at 03:13
  • Hi @Backs, i also used the same solution [ with reflection ] as our client's infrastructure team don't want any changes in machine.config file. and that also worked for me. – Intimate Dec 24 '18 at 10:28
  • 1
    in dotnet core these fields are named `s_cachedMaxTimeout` and `s_maximumTimeout` – wodzu Aug 23 '21 at 17:14