-
Notifications
You must be signed in to change notification settings - Fork 34
feat: retrieve read timestamp from read-only transaction #834
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -58,6 +58,7 @@ type contextTransaction interface { | |
| IsInBatch() bool | ||
|
|
||
| BufferWrite(ms []*spanner.Mutation) error | ||
| ReadOnlyTransactionTimestamp() (time.Time, error) | ||
| } | ||
|
|
||
| type rowIterator interface { | ||
|
|
@@ -168,6 +169,13 @@ func (d *delegatingTransaction) Rollback() error { | |
| return d.contextTransaction.Rollback() | ||
| } | ||
|
|
||
| func (d *delegatingTransaction) ReadOnlyTransactionTimestamp() (time.Time, error) { | ||
| if err := d.ensureActivated(); err != nil { | ||
| return time.Time{}, err | ||
| } | ||
| return d.contextTransaction.ReadOnlyTransactionTimestamp() | ||
| } | ||
|
|
||
| func (d *delegatingTransaction) resetForRetry(ctx context.Context) error { | ||
| if d.contextTransaction == nil { | ||
| return status.Error(codes.FailedPrecondition, "a transaction can only be reset after it has been activated") | ||
|
|
@@ -371,6 +379,16 @@ func (tx *readOnlyTransaction) BufferWrite([]*spanner.Mutation) error { | |
| return spanner.ToSpannerError(status.Errorf(codes.FailedPrecondition, "read-only transactions cannot write")) | ||
| } | ||
|
|
||
| func (tx *readOnlyTransaction) ReadOnlyTransactionTimestamp() (time.Time, error) { | ||
| if tx.roTx != nil { | ||
| return tx.roTx.Timestamp() | ||
| } | ||
| if tx.boTx != nil { | ||
| return tx.boTx.Timestamp() | ||
| } | ||
| return time.Time{}, spanner.ToSpannerError(status.Error(codes.FailedPrecondition, "underlying read-only transaction is not initialized")) | ||
| } | ||
|
Comment on lines
+382
to
+390
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The check func (tx *readOnlyTransaction) ReadOnlyTransactionTimestamp() (time.Time, error) {
if tx.roTx != nil {
return tx.roTx.Timestamp()
}
return time.Time{}, spanner.ToSpannerError(status.Error(codes.FailedPrecondition, "underlying read-only transaction is not initialized"))
} |
||
|
|
||
| // ErrAbortedDueToConcurrentModification is returned by a read/write transaction | ||
| // that was aborted by Cloud Spanner, and where the internal retry attempt | ||
| // failed because it detected that the results during the retry were different | ||
|
|
@@ -810,6 +828,10 @@ func (tx *readWriteTransaction) BufferWrite(ms []*spanner.Mutation) error { | |
| return tx.rwTx.BufferWrite(ms) | ||
| } | ||
|
|
||
| func (tx *readWriteTransaction) ReadOnlyTransactionTimestamp() (time.Time, error) { | ||
| return time.Time{}, spanner.ToSpannerError(status.Error(codes.FailedPrecondition, "cannot retrieve read timestamp on a read-write transaction")) | ||
| } | ||
|
|
||
| // errorsEqualForRetry returns true if the two errors should be considered equal | ||
| // when retrying a transaction. This comparison will return true if: | ||
| // - The errors are the same instances | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calling
d.ensureActivated()here is inefficient because it forces the activation/creation of the underlying Spanner transaction even if no query has been executed yet. Since a transaction cannot have a read timestamp before any query is run, we can avoid this overhead by checking ifd.contextTransactionisniland returning the appropriate error directly based on the transaction's read-only/read-write configuration.