Skip to content

Commit 8136588

Browse files
author
William Li
authored
Merge pull request #21102 from wli3/transaction-aborted3
Fix 10 minutes time out of TransactionScope
2 parents 63a82ab + b888bd0 commit 8136588

File tree

1 file changed

+46
-10
lines changed

1 file changed

+46
-10
lines changed

src/Cli/dotnet/TransactionalAction.cs

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,19 @@
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

44
using System;
5+
using System.Reflection;
56
using System.Transactions;
7+
using Microsoft.DotNet.Cli.Utils;
68

79
namespace Microsoft.DotNet.Cli
810
{
911
public sealed class TransactionalAction
1012
{
13+
static TransactionalAction()
14+
{
15+
DisableTransactionTimeoutUpperLimit();
16+
}
17+
1118
private class EnlistmentNotification : IEnlistmentNotification
1219
{
1320
private Action _commit;
@@ -65,19 +72,44 @@ public static T Run<T>(
6572
// This automatically inherits any ambient transaction
6673
// If a transaction is inherited, completing this scope will be a no-op
6774
T result = default(T);
68-
using (var scope = new TransactionScope(
69-
TransactionScopeOption.Required,
70-
TimeSpan.Zero))
75+
try
7176
{
72-
Transaction.Current.EnlistVolatile(
73-
new EnlistmentNotification(commit, rollback),
74-
EnlistmentOptions.None);
77+
using (var scope = new TransactionScope(
78+
TransactionScopeOption.Required,
79+
TimeSpan.Zero))
80+
{
81+
Transaction.Current.EnlistVolatile(
82+
new EnlistmentNotification(commit, rollback),
83+
EnlistmentOptions.None);
7584

76-
result = action();
85+
result = action();
7786

78-
scope.Complete();
87+
scope.Complete();
88+
}
89+
90+
return result;
91+
}
92+
catch (TransactionAbortedException ex)
93+
{
94+
Reporter.Verbose.WriteLine(string.Format("TransactionAbortedException Message: {0}", ex.Message));
95+
Reporter.Verbose.WriteLine(
96+
$"Inner Exception Message: {ex?.InnerException?.Message + "---" + ex?.InnerException}");
97+
throw;
7998
}
80-
return result;
99+
}
100+
101+
private static void SetTransactionManagerField(string fieldName, object value)
102+
{
103+
typeof(TransactionManager).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Static)
104+
.SetValue(null, value);
105+
}
106+
107+
// https://github.com/dotnet/sdk/issues/21101
108+
// we should use the proper API once it is available
109+
public static void DisableTransactionTimeoutUpperLimit()
110+
{
111+
SetTransactionManagerField("s_cachedMaxTimeout", true);
112+
SetTransactionManagerField("s_maximumTimeout", TimeSpan.Zero);
81113
}
82114

83115
public static void Run(
@@ -86,7 +118,11 @@ public static void Run(
86118
Action rollback = null)
87119
{
88120
Run<object>(
89-
action: () => { action(); return null; },
121+
action: () =>
122+
{
123+
action();
124+
return null;
125+
},
90126
commit: commit,
91127
rollback: rollback);
92128
}

0 commit comments

Comments
 (0)