2
2
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
3
4
4
using System ;
5
+ using System . Reflection ;
5
6
using System . Transactions ;
7
+ using Microsoft . DotNet . Cli . Utils ;
6
8
7
9
namespace Microsoft . DotNet . Cli
8
10
{
9
11
public sealed class TransactionalAction
10
12
{
13
+ static TransactionalAction ( )
14
+ {
15
+ DisableTransactionTimeoutUpperLimit ( ) ;
16
+ }
17
+
11
18
private class EnlistmentNotification : IEnlistmentNotification
12
19
{
13
20
private Action _commit ;
@@ -65,19 +72,44 @@ public static T Run<T>(
65
72
// This automatically inherits any ambient transaction
66
73
// If a transaction is inherited, completing this scope will be a no-op
67
74
T result = default ( T ) ;
68
- using ( var scope = new TransactionScope (
69
- TransactionScopeOption . Required ,
70
- TimeSpan . Zero ) )
75
+ try
71
76
{
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 ) ;
75
84
76
- result = action ( ) ;
85
+ result = action ( ) ;
77
86
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 ;
79
98
}
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 ) ;
81
113
}
82
114
83
115
public static void Run (
@@ -86,7 +118,11 @@ public static void Run(
86
118
Action rollback = null )
87
119
{
88
120
Run < object > (
89
- action : ( ) => { action ( ) ; return null ; } ,
121
+ action : ( ) =>
122
+ {
123
+ action ( ) ;
124
+ return null ;
125
+ } ,
90
126
commit : commit ,
91
127
rollback : rollback ) ;
92
128
}
0 commit comments