Skip to content

Commit

Permalink
Merge pull request #21102 from wli3/transaction-aborted3
Browse files Browse the repository at this point in the history
Fix 10 minutes time out of TransactionScope
  • Loading branch information
William Li authored Sep 20, 2021
2 parents 63a82ab + b888bd0 commit 8136588
Showing 1 changed file with 46 additions and 10 deletions.
56 changes: 46 additions & 10 deletions src/Cli/dotnet/TransactionalAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Reflection;
using System.Transactions;
using Microsoft.DotNet.Cli.Utils;

namespace Microsoft.DotNet.Cli
{
public sealed class TransactionalAction
{
static TransactionalAction()
{
DisableTransactionTimeoutUpperLimit();
}

private class EnlistmentNotification : IEnlistmentNotification
{
private Action _commit;
Expand Down Expand Up @@ -65,19 +72,44 @@ public static T Run<T>(
// This automatically inherits any ambient transaction
// If a transaction is inherited, completing this scope will be a no-op
T result = default(T);
using (var scope = new TransactionScope(
TransactionScopeOption.Required,
TimeSpan.Zero))
try
{
Transaction.Current.EnlistVolatile(
new EnlistmentNotification(commit, rollback),
EnlistmentOptions.None);
using (var scope = new TransactionScope(
TransactionScopeOption.Required,
TimeSpan.Zero))
{
Transaction.Current.EnlistVolatile(
new EnlistmentNotification(commit, rollback),
EnlistmentOptions.None);

result = action();
result = action();

scope.Complete();
scope.Complete();
}

return result;
}
catch (TransactionAbortedException ex)
{
Reporter.Verbose.WriteLine(string.Format("TransactionAbortedException Message: {0}", ex.Message));
Reporter.Verbose.WriteLine(
$"Inner Exception Message: {ex?.InnerException?.Message + "---" + ex?.InnerException}");
throw;
}
return result;
}

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

// https://github.com/dotnet/sdk/issues/21101
// we should use the proper API once it is available
public static void DisableTransactionTimeoutUpperLimit()
{
SetTransactionManagerField("s_cachedMaxTimeout", true);
SetTransactionManagerField("s_maximumTimeout", TimeSpan.Zero);
}

public static void Run(
Expand All @@ -86,7 +118,11 @@ public static void Run(
Action rollback = null)
{
Run<object>(
action: () => { action(); return null; },
action: () =>
{
action();
return null;
},
commit: commit,
rollback: rollback);
}
Expand Down

0 comments on commit 8136588

Please sign in to comment.