Подтвердить что ты не робот

Таймаут транзакции в течение 10 минут

У меня длинный TransactionScope в С#. Я сказал, что он должен иметь длительный промежуток времени, но все же я получаю тайм-аут. Что может вызвать это?

TransactionOptions transactionOptions = new TransactionOptions();
transactionOptions.IsolationLevel = IsolationLevel.ReadCommitted;
transactionOptions.Timeout = TimeSpan.MaxValue;
using (var ts = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
{ 
    DoLongCode();
}
4b9b3361

Ответ 1

Здравствуйте, вы можете проверить maxTimeout в вашем файле конфигурации, если у вас нет этого раздела в вашем web.config или app.config

Проверьте свой файл machine.config

<configuration> 
  <system.transactions>
    <machineSettings maxTimeout=""/>
  </system.transactions>
</configuration> 

Отрегулируйте значение

Ответ 2

Для дальнейшего уточнения:

Область транзакций использует настройку конфигурации машины как максимальный тайм-аут. Таймаут по умолчанию составляет 10 минут.

Настройка конфигурации устройства на 2 часа:

      <system.transactions>
        <machineSettings maxTimeout="02:00:00"/>
      </system.transactions> 

Приложение app.config или web.config можно использовать с уменьшением до таймаута, но не может использоваться для превышения таймаута конфигурации компьютера.

Настройка конфигурации приложения на 1 час:

<system.transactions>
     <defaultSettings timeout="01:00:00" />
</system.transactions>

Кроме того, мы не получали никаких исключений, когда был достигнут предел, а также записи журнала трассировки или журнала событий.

Кроме того, объект TransactionScope имеет перегрузки конструктора, которые позволяют указывать таймаут, но я не уверен, как это обрабатывается.

Ответ 3

Чтобы транзакция заняла более 10 минут, без необходимости менять machine.config, используйте этот код

    private void SetTransactionManagerField(string fieldName, object value)
    {
        typeof(TransactionManager).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Static).SetValue(null, value);
    }

    public TransactionScope CreateTransactionScope(TimeSpan timeout)
    {
        SetTransactionManagerField("_cachedMaxTimeout", true);
        SetTransactionManagerField("_maximumTimeout", timeout);
        return new TransactionScope(TransactionScopeOption.RequiresNew, timeout);
    }

Использование:

using (var ts = CreateTransactionScope(TimeSpan.FromMinutes(20)))
{ 
    DoLongCode();
    ts.Complete();
}

Основываясь на этой статье Код статьи был первоначально вставлен здесь. Код в ответе теперь реорганизуется и упрощается.

Ответ 4

Они не работают, потому что это неправильный контекст, в котором вы пытаетесь изменить таймаут.

попытайтесь изменить его ближе к эффективному запросу.

У вас должны быть следующие контексты:

    using (var txn = new TransactionScope(
                            TransactionScopeOption.Required,
                            new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted, Timeout = new TimeSpan(1,0,0) })) // 1 hour or wathever, will not affect anything
                    {

                        using (SqlConnection connection = new SqlConnection(ConnectionString))
                        {
                            int ct = connection.ConnectionTimeout // (read Only, this is the effective default timeout is 15 seconds)
                            connection.Open();

                            SqlCommand select = new SqlCommand(sql.query, connection); // bind to server
                            select.CommandTimeout = 0; // <-- here does apply infinite timeout
SqlDataReader reader = select.ExecuteReader(); // never stop

Ответ 5

Учитывая полную среду доверия, вы можете переопределить максимальное время ожидания с помощью отражения:

            //Get machineSettings session
            var machineSettings = (System.Transactions.Configuration.MachineSettingsSection)ConfigurationManager.GetSection("system.transactions/machineSettings");
            //Allow modifications
            var bReadOnly = (typeof(ConfigurationElement)).GetField("_bReadOnly", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            bReadOnly.SetValue(machineSettings, false);
            //Change max allowed timeout
            machineSettings.MaxTimeout = TimeSpan.MaxValue;

            using (var t = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(1,0,0))) { //1 hour transaction
                //...
            }

Ответ 6

Я разрешаю эту проблему, изменяя "физический файл" machine.config.


1. Вы должны локализовать файл:

  • 32 бита: C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\machie.config
  • 64 бита: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config

2. Вам нужно добавить следующий код:

<system.transactions>
     <defaultSettings timeout="00:59:00" />
</system.transactions>

Ответ 7

При использовании транзакций с операцией WCF в цепочке вызовов у вас есть ответ на запрос и вызов msmq, отправляющий электронные письма, я получаю тайм-аут на последнем запрошенном в очереди вызове, который отправляет электронное письмо, у меня нет транзакционных разрешений на очередь в очереди.