14
14
15
15
using Google . Api . Gax ;
16
16
using Google . Cloud . Spanner . V1 ;
17
+ using System ;
17
18
using static Google . Cloud . Spanner . V1 . TransactionOptions . Types ;
18
19
19
20
namespace Google . Cloud . Spanner . Data ;
@@ -28,19 +29,19 @@ public sealed class SpannerTransactionCreationOptions
28
29
/// Options that will result in a read-write transaction.
29
30
/// </summary>
30
31
public static SpannerTransactionCreationOptions ReadWrite { get ; } = new SpannerTransactionCreationOptions (
31
- timestampBound : null , transactionId : null , isDetached : false , isSingleUse : false , isPartitionedDml : false , excludeFromChangeStreams : false ) ;
32
+ timestampBound : null , transactionId : null , isDetached : false , isSingleUse : false , isPartitionedDml : false , excludeFromChangeStreams : false , isolationLevel : IsolationLevel . Unspecified ) ;
32
33
33
34
/// <summary>
34
35
/// Options that will result in a read-write transaction suitable for executing partioned DML.
35
36
/// </summary>
36
37
public static SpannerTransactionCreationOptions PartitionedDml { get ; } = new SpannerTransactionCreationOptions (
37
- timestampBound : null , transactionId : null , isDetached : false , isSingleUse : false , isPartitionedDml : true , excludeFromChangeStreams : false ) ;
38
+ timestampBound : null , transactionId : null , isDetached : false , isSingleUse : false , isPartitionedDml : true , excludeFromChangeStreams : false , isolationLevel : IsolationLevel . Unspecified ) ;
38
39
39
40
/// <summary>
40
41
/// Options that will result in a read-only transaction bound by <see cref="TimestampBound.Strong"/>.
41
42
/// </summary>
42
43
public static SpannerTransactionCreationOptions ReadOnly { get ; } = new SpannerTransactionCreationOptions (
43
- TimestampBound . Strong , transactionId : null , isDetached : false , isSingleUse : false , isPartitionedDml : false , excludeFromChangeStreams : false ) ;
44
+ TimestampBound . Strong , transactionId : null , isDetached : false , isSingleUse : false , isPartitionedDml : false , excludeFromChangeStreams : false , isolationLevel : IsolationLevel . Unspecified ) ;
44
45
45
46
/// <summary>
46
47
/// Timestamp bound settings for the transaction. May be null.
@@ -92,6 +93,13 @@ public sealed class SpannerTransactionCreationOptions
92
93
/// </summary>
93
94
public bool IsPartitionedDml { get ; }
94
95
96
+ /// <summary>
97
+ /// Set the isolation level for the transaction. This is only meant for read-write transactions.
98
+ /// <see cref="TransactionOptions.Types.IsolationLevel"/> to reference the possible configuration values.
99
+ /// When this is set to other than ISOLATION_LEVEL_UNSPECIFIED the transaction will be read-write.
100
+ /// </summary>
101
+ public IsolationLevel IsolationLevel { get ; }
102
+
95
103
/// <summary>
96
104
/// Whether changes executed within this transaction are recorded in change streams or not.
97
105
/// This will always be false for read-only transactions.
@@ -105,7 +113,7 @@ public sealed class SpannerTransactionCreationOptions
105
113
/// </remarks>
106
114
public bool ExcludeFromChangeStreams { get ; }
107
115
108
- private SpannerTransactionCreationOptions ( TimestampBound timestampBound , TransactionId transactionId , bool isDetached , bool isSingleUse , bool isPartitionedDml , bool excludeFromChangeStreams )
116
+ private SpannerTransactionCreationOptions ( TimestampBound timestampBound , TransactionId transactionId , bool isDetached , bool isSingleUse , bool isPartitionedDml , bool excludeFromChangeStreams , IsolationLevel isolationLevel )
109
117
{
110
118
GaxPreconditions . CheckArgument (
111
119
timestampBound is null || transactionId is null ,
@@ -137,6 +145,11 @@ private SpannerTransactionCreationOptions(TimestampBound timestampBound, Transac
137
145
nameof ( excludeFromChangeStreams ) ,
138
146
"Only read-write and partioned DML transactions can be marked for change stream exclusion." ) ;
139
147
ExcludeFromChangeStreams = excludeFromChangeStreams ;
148
+ GaxPreconditions . CheckArgument (
149
+ isolationLevel != IsolationLevel . Unspecified && TimestampBound == TimestampBound . Strong ,
150
+ nameof ( isolationLevel ) ,
151
+ $ "{ nameof ( isolationLevel ) } cannot be set on a Read-only transaction"
152
+ ) ;
140
153
}
141
154
142
155
/// <summary>
@@ -155,7 +168,8 @@ timestampBound is null
155
168
isDetached : false ,
156
169
isSingleUse : timestampBound ? . Mode == TimestampBoundMode . MinReadTimestamp || timestampBound ? . Mode == TimestampBoundMode . MaxStaleness ,
157
170
isPartitionedDml : false ,
158
- excludeFromChangeStreams : false ) ;
171
+ excludeFromChangeStreams : false ,
172
+ isolationLevel : IsolationLevel . Unspecified ) ;
159
173
160
174
/// <summary>
161
175
/// Creates transaction options with the given <paramref name="transactionId"/>.
@@ -170,15 +184,16 @@ public static SpannerTransactionCreationOptions FromReadOnlyTransactionId(Transa
170
184
isDetached : true ,
171
185
isSingleUse : false ,
172
186
isPartitionedDml : false ,
173
- excludeFromChangeStreams : false ) ;
187
+ excludeFromChangeStreams : false ,
188
+ isolationLevel : IsolationLevel . Unspecified ) ;
174
189
175
190
/// <summary>
176
191
/// Options used to acquire the transaction's underlying session.
177
192
/// </summary>
178
193
internal TransactionOptions GetTransactionOptions ( )
179
194
{
180
- var options = IsPartitionedDml ? new TransactionOptions { PartitionedDml = new PartitionedDml ( ) } :
181
- TransactionMode == TransactionMode . ReadWrite ? new TransactionOptions { ReadWrite = new ReadWrite ( ) } :
195
+ var options = IsPartitionedDml ? new TransactionOptions { PartitionedDml = new PartitionedDml ( ) , IsolationLevel = IsolationLevel . Unspecified } :
196
+ TransactionMode == TransactionMode . ReadWrite ? new TransactionOptions { ReadWrite = new ReadWrite ( ) , IsolationLevel = IsolationLevel } :
182
197
TimestampBound ? . ToTransactionOptions ( ) ;
183
198
if ( options is not null )
184
199
{
@@ -192,7 +207,7 @@ internal TransactionOptions GetTransactionOptions()
192
207
/// If <see cref="TransactionId"/> is set, <see cref="IsDetached"/> cannot be false.
193
208
/// </summary>
194
209
public SpannerTransactionCreationOptions WithIsDetached ( bool isDetached ) =>
195
- isDetached == IsDetached ? this : new SpannerTransactionCreationOptions ( TimestampBound , TransactionId , isDetached , IsSingleUse , IsPartitionedDml , ExcludeFromChangeStreams ) ;
210
+ isDetached == IsDetached ? this : new SpannerTransactionCreationOptions ( TimestampBound , TransactionId , isDetached , IsSingleUse , IsPartitionedDml , ExcludeFromChangeStreams , IsolationLevel ) ;
196
211
197
212
/// <summary>
198
213
/// Returns a new instance identical to this one except for the value of <see cref="IsSingleUse"/>.
@@ -201,12 +216,18 @@ public SpannerTransactionCreationOptions WithIsDetached(bool isDetached) =>
201
216
/// <see cref="IsSingleUse"/> cannot be false.
202
217
/// </summary>
203
218
public SpannerTransactionCreationOptions WithIsSingleUse ( bool isSingleUse ) =>
204
- isSingleUse == IsSingleUse ? this : new SpannerTransactionCreationOptions ( TimestampBound , TransactionId , IsDetached , isSingleUse , IsPartitionedDml , ExcludeFromChangeStreams ) ;
219
+ isSingleUse == IsSingleUse ? this : new SpannerTransactionCreationOptions ( TimestampBound , TransactionId , IsDetached , isSingleUse , IsPartitionedDml , ExcludeFromChangeStreams , IsolationLevel ) ;
205
220
206
221
/// <summary>
207
222
/// Returns a new instance identical to this one except for the value of <see cref="ExcludeFromChangeStreams"/>.
208
223
/// <see cref="ExcludeFromChangeStreams"/> can only be true for read-write transactions.
209
224
/// </summary>
210
225
public SpannerTransactionCreationOptions WithExcludeFromChangeStreams ( bool excludeFromChangeStreams ) =>
211
- excludeFromChangeStreams == ExcludeFromChangeStreams ? this : new SpannerTransactionCreationOptions ( TimestampBound , TransactionId , IsDetached , IsSingleUse , IsPartitionedDml , excludeFromChangeStreams ) ;
226
+ excludeFromChangeStreams == ExcludeFromChangeStreams ? this : new SpannerTransactionCreationOptions ( TimestampBound , TransactionId , IsDetached , IsSingleUse , IsPartitionedDml , excludeFromChangeStreams , IsolationLevel ) ;
227
+
228
+ /// <summary>
229
+ /// Returns a new instance identical to this one except for the value of <see cref="IsolationLevel"/>
230
+ /// </summary>
231
+ public SpannerTransactionCreationOptions WithIsolationLevel ( IsolationLevel isolationLevel ) =>
232
+ isolationLevel == IsolationLevel ? this : new SpannerTransactionCreationOptions ( TimestampBound , TransactionId , IsDetached , IsSingleUse , IsPartitionedDml , ExcludeFromChangeStreams , isolationLevel ) ;
212
233
}
0 commit comments