Skip to content

Commit 970dd8e

Browse files
committed
refactor(Spanner): Simplify access to a transaction's timestamp bound information
1 parent e7e527b commit 970dd8e

File tree

4 files changed

+26
-11
lines changed

4 files changed

+26
-11
lines changed

apis/Google.Cloud.Spanner.Data/Google.Cloud.Spanner.Data.Tests/SpannerTransactionCreationOptionsTests.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public void ReadWrite_Values()
5656

5757
Assert.Null(readWrite.TimestampBound);
5858
Assert.Null(readWrite.TransactionId);
59+
Assert.Null(readWrite.EffectiveTimestampBound);
5960
Assert.Equal(TransactionMode.ReadWrite, readWrite.TransactionMode);
6061
Assert.False(readWrite.IsDetached);
6162
Assert.False(readWrite.IsSingleUse);
@@ -73,6 +74,7 @@ public void PartitionedDml_Values()
7374

7475
Assert.Null(partitionedDml.TimestampBound);
7576
Assert.Null(partitionedDml.TransactionId);
77+
Assert.Null(partitionedDml.EffectiveTimestampBound);
7678
Assert.Equal(TransactionMode.ReadWrite, partitionedDml.TransactionMode);
7779
Assert.False(partitionedDml.IsDetached);
7880
Assert.False(partitionedDml.IsSingleUse);
@@ -90,6 +92,7 @@ public void ReadOnly_Values()
9092

9193
Assert.Equal(TimestampBound.Strong, readOnly.TimestampBound);
9294
Assert.Null(readOnly.TransactionId);
95+
Assert.Equal(TimestampBound.Strong, readOnly.EffectiveTimestampBound);
9396
Assert.Equal(TransactionMode.ReadOnly, readOnly.TransactionMode);
9497
Assert.False(readOnly.IsDetached);
9598
Assert.False(readOnly.IsSingleUse);
@@ -106,6 +109,7 @@ public void ForTimestampBoundReadOnly_Null()
106109
var options = SpannerTransactionCreationOptions.ForTimestampBoundReadOnly(null);
107110
Assert.Equal(TimestampBound.Strong, options.TimestampBound);
108111
Assert.Null(options.TransactionId);
112+
Assert.Equal(TimestampBound.Strong, options.EffectiveTimestampBound);
109113
Assert.Equal(TransactionMode.ReadOnly, options.TransactionMode);
110114
Assert.False(options.IsDetached);
111115
Assert.False(options.IsSingleUse);
@@ -123,6 +127,7 @@ public void ForTimestampBoundReadOnly_Custom()
123127
var options = SpannerTransactionCreationOptions.ForTimestampBoundReadOnly(timestampBound);
124128
Assert.Equal(timestampBound, options.TimestampBound);
125129
Assert.Null(options.TransactionId);
130+
Assert.Equal(timestampBound, options.EffectiveTimestampBound);
126131
Assert.Equal(TransactionMode.ReadOnly, options.TransactionMode);
127132
Assert.False(options.IsDetached);
128133
Assert.True(options.IsSingleUse);
@@ -145,13 +150,14 @@ public void FromReadOnlyTransactionId_NotNull()
145150
var options = SpannerTransactionCreationOptions.FromReadOnlyTransactionId(transactionId);
146151
Assert.Equal(transactionId, options.TransactionId);
147152
Assert.Null(options.TimestampBound);
153+
Assert.Equal(TimestampBound.Strong, options.EffectiveTimestampBound);
148154
Assert.Equal(TransactionMode.ReadOnly, options.TransactionMode);
149155
Assert.True(options.IsDetached);
150156
Assert.False(options.IsSingleUse);
151157
Assert.False(options.IsPartitionedDml);
152158
Assert.False(options.ExcludeFromChangeStreams);
153159
Assert.Equal(IsolationLevel.Unspecified, options.IsolationLevel);
154-
Assert.Null(options.GetTransactionOptions());
160+
Assert.Equal(TimestampBound.Strong.ToTransactionOptions(), options.GetTransactionOptions());
155161
Assert.Equal(ReadLockMode.Unspecified, options.ReadLockMode);
156162
}
157163

apis/Google.Cloud.Spanner.Data/Google.Cloud.Spanner.Data/SpannerConnection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ internal Task<SpannerTransaction> BeginTransactionAsyncImpl(
592592
{
593593
SessionName sessionName = SessionName.Parse(transactionCreationOptions.TransactionId.Session);
594594
ByteString transactionIdBytes = ByteString.FromBase64(transactionCreationOptions.TransactionId.Id);
595-
var timestamp = transactionCreationOptions.TransactionId.TimestampBound?.Timestamp;
595+
var timestamp = transactionCreationOptions.EffectiveTimestampBound?.Timestamp;
596596
var readTimestamp = timestamp.HasValue ? Protobuf.WellKnownTypes.Timestamp.FromDateTime(timestamp.Value) : null;
597597
transaction = ManagedTransaction.FromTransaction(
598598
_managedSession.Client, new Session { SessionName = sessionName }, transactionIdBytes, transactionCreationOptions.GetTransactionOptions(), readTimestamp);

apis/Google.Cloud.Spanner.Data/Google.Cloud.Spanner.Data/SpannerTransaction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public int CommitTimeout
151151
/// </list>
152152
/// </para>
153153
/// </remarks>
154-
public TimestampBound TimestampBound => _creationOptions.TimestampBound ?? _creationOptions.TransactionId?.TimestampBound;
154+
public TimestampBound TimestampBound => _creationOptions.EffectiveTimestampBound;
155155

156156
/// <inheritdoc />
157157
protected override DbConnection DbConnection => SpannerConnection;

apis/Google.Cloud.Spanner.Data/Google.Cloud.Spanner.Data/SpannerTransactionCreationOptions.cs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ public sealed class SpannerTransactionCreationOptions
6262
/// </summary>
6363
public TransactionId TransactionId { get; }
6464

65+
internal TimestampBound EffectiveTimestampBound => TimestampBound ?? TransactionId?.TimestampBound;
66+
private TransactionOptions EffectiveTimestampBoundTxnOptions => EffectiveTimestampBound?.ToTransactionOptions();
67+
6568
/// <summary>
6669
/// Whether these options should result in a detached transaction or in one that's tracked by a session pool.
6770
/// This will always be true when <see cref="TransactionId"/> is set. Otherwise it will be false unless explicitly
@@ -206,9 +209,15 @@ public static SpannerTransactionCreationOptions FromReadOnlyTransactionId(Transa
206209
/// </summary>
207210
internal TransactionOptions GetTransactionOptions()
208211
{
209-
var options = IsPartitionedDml ? new TransactionOptions { PartitionedDml = new PartitionedDml() } :
210-
TransactionMode == TransactionMode.ReadWrite ? new TransactionOptions { ReadWrite = new ReadWrite() } :
211-
TimestampBound?.ToTransactionOptions();
212+
TransactionOptions options = this switch
213+
{
214+
{ IsPartitionedDml: true } => new TransactionOptions { PartitionedDml = new PartitionedDml() },
215+
{ TransactionMode: TransactionMode.ReadWrite } => new TransactionOptions { ReadWrite = new ReadWrite() },
216+
{ EffectiveTimestampBoundTxnOptions: var txnOptions } when txnOptions is not null => txnOptions,
217+
{ TransactionId: var txnId } when txnId is not null => new TransactionOptions { ReadOnly = new ReadOnly() },
218+
_ => null
219+
};
220+
212221
if (options is not null)
213222
{
214223
options.ExcludeTxnFromChangeStreams = ExcludeFromChangeStreams;
@@ -233,11 +242,11 @@ internal TransactionOptions GetTransactionOptions()
233242
return options;
234243
}
235244

236-
/// <summary>
237-
/// Returns a new instance identical to this one except for the value of <see cref="IsDetached"/>.
238-
/// If <see cref="TransactionId"/> is set, <see cref="IsDetached"/> cannot be false.
239-
/// </summary>
240-
public SpannerTransactionCreationOptions WithIsDetached(bool isDetached) =>
245+
/// <summary>
246+
/// Returns a new instance identical to this one except for the value of <see cref="IsDetached"/>.
247+
/// If <see cref="TransactionId"/> is set, <see cref="IsDetached"/> cannot be false.
248+
/// </summary>
249+
public SpannerTransactionCreationOptions WithIsDetached(bool isDetached) =>
241250
isDetached == IsDetached ? this : new SpannerTransactionCreationOptions(TimestampBound, TransactionId, isDetached, IsSingleUse, IsPartitionedDml, ExcludeFromChangeStreams, IsolationLevel, ReadLockMode);
242251

243252
/// <summary>

0 commit comments

Comments
 (0)