google-cloud-spanner 2.28.0 → 2.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -509,25 +509,9 @@ module Google
509
509
  # Required.
510
510
  # @param [String] database_id The unique identifier for the database.
511
511
  # Required.
512
- # @param [Hash] pool Settings to control how and when sessions are
513
- # managed by the client. The following settings can be provided:
514
- #
515
- # * `:min` (Integer) Minimum number of sessions that the client will
516
- # maintain at any point in time. The default is 10.
517
- # * `:max` (Integer) Maximum number of sessions that the client will
518
- # have at any point in time. The default is 100.
519
- # * `:keepalive` (Numeric) The amount of time a session can be idle
520
- # before an attempt is made to prevent the idle sessions from being
521
- # closed by the Cloud Spanner service. The default is 1800 (30
522
- # minutes).
523
- # * `:fail` (true/false) When `true` the client raises a
524
- # {SessionLimitError} when the client has allocated the `max` number
525
- # of sessions. When `false` the client blocks until a session
526
- # becomes available. The default is `true`.
527
- # * `:threads` (Integer) The number of threads in the thread pool. The
528
- # default is twice the number of available CPUs.
529
- # * `:write_ratio` (Float) Deprecated. This field is no longer needed
530
- # and will be removed in a future release.
512
+ # @param [Hash] pool Optional. Defaults to `{}`. Deprecated.
513
+ # @deprecated This parameter is non-functional since the multiplexed SessionCache does not require
514
+ # pool options.
531
515
  # @param [Hash] labels The labels to be applied to all sessions
532
516
  # created by the client. Cloud Labels are a flexible and lightweight
533
517
  # mechanism for organizing cloud resources into groups that reflect a
@@ -567,7 +551,7 @@ module Google
567
551
  # Spanner will wait for a replica in the list to become available,
568
552
  # requests may fail due to DEADLINE_EXCEEDED errors.
569
553
  #
570
- # @return [Client] The newly created client.
554
+ # @return [::Google::Cloud::Spanner::Client] The newly created client.
571
555
  #
572
556
  # @example
573
557
  # require "google/cloud/spanner"
@@ -594,9 +578,11 @@ module Google
594
578
  else
595
579
  query_options = query_options.merge @query_options unless @query_options.nil?
596
580
  end
581
+
582
+ _pool = pool # unused. Here only to avoid having to disable Rubocop's Lint/UnusedMethodArgument
583
+
597
584
  Client.new self, instance_id, database_id,
598
585
  session_labels: labels,
599
- pool_opts: valid_session_pool_options(pool),
600
586
  query_options: query_options,
601
587
  database_role: database_role,
602
588
  directed_read_options: directed_read_options
@@ -649,7 +635,7 @@ module Google
649
635
  # Spanner will wait for a replica in the list to become available,
650
636
  # requests may fail due to DEADLINE_EXCEEDED errors.
651
637
  #
652
- # @return [Client] The newly created client.
638
+ # @return [::Google::Cloud::Spanner::BatchClient] The newly created client.
653
639
  #
654
640
  # @example
655
641
  # require "google/cloud/spanner"
@@ -45,32 +45,42 @@ module Google
45
45
  # end
46
46
  #
47
47
  class Results
48
- # The `V1::ResultSetMetadata` protobuf object from the first
49
- # PartialResultSet.
50
- # @private
51
- # @return [::Google::Cloud::Spanner::V1::ResultSetMetadata]
52
- attr_reader :metadata
53
-
54
48
  # Creates a new Results instance.
55
49
  # @param service [::Google::Cloud::Spanner::Service] The `Spanner::Service` reference.
56
50
  # @param partial_result_sets [::Enumerable<::Google::Cloud::Spanner::V1::PartialResultSet>]
57
51
  # Raw enumerable from grpc `StreamingRead` call.
58
52
  # @param session_name [::String] Required.
59
- # The session in which the transaction to be committed is running.
53
+ # The name of the session for the operation that created these Results.
60
54
  # Values are of the form:
61
55
  # `projects/<project_id>/instances/<instance_id>/databases/<database_id>/sessions/<session_id>`.
62
56
  # @param metadata [::Google::Cloud::Spanner::V1::ResultSetMetadata] ParialResultSet metadata object
63
57
  # @param stats [::Google::Cloud::Spanner::V1::ResultSetStats] Query plan and execution statistics
64
58
  # for the statement that produced this streaming result set.
59
+ # @param precommit_token_notify [::Proc, nil] Optional.
60
+ # The notification function for the precommit token.
65
61
  # @private
66
- def initialize service, partial_result_sets, session_name, metadata, stats
62
+ def initialize service, partial_result_sets, session_name, metadata, stats, precommit_token_notify: nil
67
63
  @service = service
68
64
  @partial_result_sets = partial_result_sets
69
65
  @session_name = session_name
70
66
  @metadata = metadata
71
67
  @stats = stats
68
+
69
+ # The notification function for the precommit token.
70
+ # `Results` object will see precommit tokens while iterating if it were created
71
+ # in the context of an RW transaction on a multiplexed session.
72
+ # Precommit token is a passthrough parameter that that transaction will need to supply in order to Commit.
73
+ # There can be multiple precommit tokens in the stream
74
+ # (should be at least 2 -- with the first and last PartialResultSet).
75
+ @precommit_token_notify = precommit_token_notify
72
76
  end
73
77
 
78
+ # The `V1::ResultSetMetadata` protobuf object from the first
79
+ # PartialResultSet.
80
+ # @private
81
+ # @return [::Google::Cloud::Spanner::V1::ResultSetMetadata]
82
+ attr_reader :metadata
83
+
74
84
  ##
75
85
  # The read timestamp chosen for single-use snapshots (read-only
76
86
  # transactions).
@@ -162,13 +172,21 @@ module Google
162
172
  should_retry_request = false
163
173
  end
164
174
 
165
- # @type [::Google::Cloud::Spanner::V1::PartialResultsSet]
175
+ # @type [::Google::Cloud::Spanner::V1::PartialResultSet]
166
176
  grpc = @partial_result_sets.next
167
177
 
168
178
  # metadata should be set before the first iteration...
169
179
  @metadata ||= grpc.metadata
170
180
  @stats ||= grpc.stats
171
181
 
182
+ # The precommit token should be issued on first and last stream element.
183
+ # These two precommit tokens can be different.
184
+ # If these Results are created in the context of a `Spanner::Transaction`,
185
+ # that `Transaction` object is the one keeping track of the precommit token and should be notified.
186
+ if grpc.precommit_token && @precommit_token_notify
187
+ @precommit_token_notify.call(grpc.precommit_token)
188
+ end
189
+
172
190
  buffered_responses << grpc
173
191
 
174
192
  if (grpc.resume_token && grpc.resume_token != "") ||
@@ -327,17 +345,26 @@ module Google
327
345
  # Raw enumerable from underlying grpc call.
328
346
  # @param service [::Google::Cloud::Spanner::Service] The `Spanner::Service` reference.
329
347
  # @param session_name [::String] Required.
330
- # The session in which the transaction to be committed is running.
348
+ # The name of the session for the operation that created these Results.
331
349
  # Values are of the form:
332
350
  # `projects/<project_id>/instances/<instance_id>/databases/<database_id>/sessions/<session_id>`.
351
+ # @param precommit_token_notify [::Proc, nil] Optional.
352
+ # The notification function for the precommit token.
333
353
  # @private
334
354
  # @return [::Google::Cloud::Spanner::Results]
335
- def self.from_partial_result_sets partial_result_sets, service, session_name
355
+ def self.from_partial_result_sets partial_result_sets, service, session_name, precommit_token_notify: nil
336
356
  # @type [::Google::Cloud::Spanner::V1::PartialResultSet]
337
357
  partial_result_set = partial_result_sets.peek
338
358
  metadata = partial_result_set.metadata
339
359
  stats = partial_result_set.stats
340
- new service, partial_result_sets, session_name, metadata, stats
360
+ results = new service, partial_result_sets, session_name, metadata, stats,
361
+ precommit_token_notify: precommit_token_notify
362
+
363
+ if partial_result_set.precommit_token && precommit_token_notify
364
+ precommit_token_notify.call partial_result_set.precommit_token
365
+ end
366
+
367
+ results
341
368
  rescue GRPC::BadStatus => e
342
369
  raise Google::Cloud::Error.from_error(e)
343
370
  end
@@ -355,10 +382,14 @@ module Google
355
382
  # that were sent to the `service.execute_streaming_sql`. This hash joins params needed to
356
383
  # construct `::Gapic::CallOptions`, e.g. `call_options` and header-related `route_to_leader`
357
384
  # with params specific to `execute_streaming_sql`, such as `seqno`.
385
+ # @param precommit_token_notify [::Proc, nil] Optional.
386
+ # The notification function for the precommit token.
358
387
  # @private
359
388
  # @return [::Google::Cloud::Spanner::Results]
360
- def self.from_execute_query_response response, service, session_name, sql, execute_query_options
361
- from_partial_result_sets(response, service, session_name).tap do |results|
389
+ def self.from_execute_query_response response, service, session_name, sql, execute_query_options,
390
+ precommit_token_notify: nil
391
+ from_partial_result_sets(response, service, session_name,
392
+ precommit_token_notify: precommit_token_notify).tap do |results|
362
393
  execute_query_options_copy = execute_query_options.dup
363
394
  unless results.metadata.transaction.nil?
364
395
  execute_query_options_copy[:transaction] = V1::TransactionSelector.new id: results.metadata.transaction.id
@@ -384,10 +415,14 @@ module Google
384
415
  # that were sent to the `service.streaming_read_table`. This hash joins params needed to
385
416
  # construct `::Gapic::CallOptions`, e.g. `call_options` and header-related `route_to_leader`
386
417
  # with params specific to `streaming_read_table`, such as `keys`.
418
+ # @param precommit_token_notify [::Proc, nil] Optional.
419
+ # The notification function for the precommit token.
387
420
  # @private
388
421
  # @return [::Google::Cloud::Spanner::Results]
389
- def self.from_read_response response, service, session_name, table, columns, read_options
390
- from_partial_result_sets(response, service, session_name).tap do |results|
422
+ def self.from_read_response response, service, session_name, table, columns, read_options,
423
+ precommit_token_notify: nil
424
+ from_partial_result_sets(response, service, session_name,
425
+ precommit_token_notify: precommit_token_notify).tap do |results|
391
426
  read_options_copy = read_options.dup
392
427
  unless results.metadata.transaction.nil?
393
428
  read_options_copy[:transaction] = V1::TransactionSelector.new id: results.metadata.transaction.id
@@ -352,17 +352,17 @@ module Google
352
352
  # @param database_name [::String] The full name of the database.
353
353
  # @param labels [::Hash, nil] Optional. The labels to be applied to all sessions
354
354
  # created by the client. Example: `"team" => "billing-service"`.
355
- # @param call_options [::Hash, nil] Optional. A hash of values to specify the custom
356
- # call options. Example option `:timeout`.
357
355
  # @param database_role [::String, nil] Optional. The Spanner session creator role.
358
356
  # Example: `analyst`.
359
357
  # @param multiplexed [::Boolean] Optional. Default to `false`.
360
358
  # If `true`, specifies a multiplexed session.
359
+ # @param call_options [::Hash, nil] Optional. A hash of values to specify the custom
360
+ # call options. Example option `:timeout`.
361
361
  # @return [::Google::Cloud::Spanner::V1::Session]
362
362
  # @private
363
363
  def create_session database_name, labels: nil,
364
- call_options: nil, database_role: nil,
365
- multiplexed: false
364
+ database_role: nil, multiplexed: false,
365
+ call_options: nil
366
366
  route_to_leader = LARHeaders.create_session
367
367
  opts = default_options(
368
368
  session_name: database_name,
@@ -530,11 +530,15 @@ module Google
530
530
  # Example option: `:priority`.
531
531
  # @param call_options [::Hash, nil] Optional. A hash of values to specify the custom
532
532
  # call options. Example option `:timeout`.
533
+ # @param precommit_token [::Google::Cloud::Spanner::V1::MultiplexedSessionPrecommitToken, nil] Optional.
534
+ # If the read-write transaction was executed on a multiplexed session, then a precommit token
535
+ # with the highest sequence number received in this transaction attempt must be included.
533
536
  # @private
534
537
  # @return [::Google::Cloud::Spanner::V1::CommitResponse]
535
538
  def commit session_name, mutations = [],
536
539
  transaction_id: nil, exclude_txn_from_change_streams: false,
537
- commit_options: nil, request_options: nil, call_options: nil
540
+ commit_options: nil, request_options: nil, call_options: nil,
541
+ precommit_token: nil
538
542
  route_to_leader = LARHeaders.commit
539
543
  tx_opts = nil
540
544
  if transaction_id.nil?
@@ -549,7 +553,7 @@ module Google
549
553
  request = {
550
554
  session: session_name, transaction_id: transaction_id,
551
555
  single_use_transaction: tx_opts, mutations: mutations,
552
- request_options: request_options
556
+ request_options: request_options, precommit_token: precommit_token
553
557
  }
554
558
 
555
559
  request = add_commit_options request, commit_options
@@ -617,24 +621,44 @@ module Google
617
621
  # @param route_to_leader [::String, nil] Optional. The value to be sent
618
622
  # as `x-goog-spanner-route-to-leader` header for leader aware routing.
619
623
  # Expected values: `"true"` or `"false"`.
624
+ # @param mutation_key [::Google::Cloud::Spanner::V1::Mutation, nil] Optional.
625
+ # If a read-write transaction on a multiplexed session commit mutations
626
+ # without performing any reads or queries, one of the mutations from the mutation set
627
+ # must be sent as a mutation key for `BeginTransaction`.
628
+ # @param previous_transaction_id [::String, nil] Optional.
629
+ # An id of the previous transaction, if this new transaction wrapper is being created
630
+ # as a part of a retry. Previous transaction id should be added to TransactionOptions
631
+ # of a new ReadWrite transaction when retry is attempted.
620
632
  # @private
621
633
  # @return [::Google::Cloud::Spanner::V1::Transaction]
622
634
  def begin_transaction session_name,
623
635
  exclude_txn_from_change_streams: false,
624
636
  request_options: nil,
625
637
  call_options: nil,
626
- route_to_leader: nil
638
+ route_to_leader: nil,
639
+ mutation_key: nil,
640
+ previous_transaction_id: nil
641
+ read_write = if previous_transaction_id.nil?
642
+ V1::TransactionOptions::ReadWrite.new
643
+ else
644
+ V1::TransactionOptions::ReadWrite.new(
645
+ multiplexed_session_previous_transaction_id: previous_transaction_id
646
+ )
647
+ end
648
+
627
649
  tx_opts = V1::TransactionOptions.new(
628
- read_write: V1::TransactionOptions::ReadWrite.new,
650
+ read_write: read_write,
629
651
  exclude_txn_from_change_streams: exclude_txn_from_change_streams
630
652
  )
653
+
631
654
  opts = default_options session_name: session_name,
632
655
  call_options: call_options,
633
656
  route_to_leader: route_to_leader
634
657
  request = {
635
658
  session: session_name,
636
659
  options: tx_opts,
637
- request_options: request_options
660
+ request_options: request_options,
661
+ mutation_key: mutation_key
638
662
  }
639
663
  service.begin_transaction request, opts
640
664
  end
@@ -657,6 +681,28 @@ module Google
657
681
  service.batch_write request, opts
658
682
  end
659
683
 
684
+ # Creates a specialized `V1::Transaction` object. Reads on that object will have
685
+ # at most one of following consistency properties:
686
+ # * reading all previously commited transactions
687
+ # * reading all data from a given timestamp
688
+ # * reading all data from a timestamp that is exactly a given value old
689
+ # (the last one sidesteps worries of client-server time skew).
690
+ #
691
+ # Having at _least_ one of those is not enforced so this can create normal transactions
692
+ # as well.
693
+ # Created transactions will include the the read timestamp chosen for the transaction.
694
+ # @param session_name [::String] Required.
695
+ # Required. The session in which the snapshot transaction is to be created..
696
+ # Values are of the form:
697
+ # `projects/<project_id>/instances/<instance_id>/databases/<database_id>/sessions/<session_id>`.
698
+ # @param strong [::Boolean, nil] Optional.
699
+ # Whether this transaction should have strong consistency.
700
+ # @param timestamp [::String, ::Date ::Time, nil] Optional.
701
+ # Timestamp that the reads should be executed at. Reads are repeatable with this option.
702
+ # @param staleness [::Numeric, nil] Optional.
703
+ # The offset of staleness that the reads should be executed at.
704
+ # @param call_options [::Hash, nil] Optional. A hash of values to specify the custom
705
+ # call options. Example option `:timeout`.
660
706
  def create_snapshot session_name, strong: nil, timestamp: nil,
661
707
  staleness: nil, call_options: nil
662
708
  tx_opts = V1::TransactionOptions.new(
@@ -671,7 +717,7 @@ module Google
671
717
  )
672
718
  opts = default_options session_name: session_name,
673
719
  call_options: call_options
674
- request = { session: session_name, options: tx_opts }
720
+ request = { session: session_name, options: tx_opts, mutation_key: nil }
675
721
  service.begin_transaction request, opts
676
722
  end
677
723
 
@@ -686,7 +732,7 @@ module Google
686
732
  opts = default_options session_name: session_name,
687
733
  call_options: call_options,
688
734
  route_to_leader: route_to_leader
689
- request = { session: session_name, options: tx_opts }
735
+ request = { session: session_name, options: tx_opts, mutation_key: nil }
690
736
  service.begin_transaction request, opts
691
737
  end
692
738
 
@@ -829,6 +875,21 @@ module Google
829
875
  value << " gccl"
830
876
  end
831
877
 
878
+ # Creates new `Gapic::CallOptions` from typical parameters for Spanner RPC calls.
879
+ #
880
+ # @param session_name [::String, nil] Optional.
881
+ # The session name. Used to extract the routing header. The value will be
882
+ # used to send the old `google-cloud-resource-prefix` routing header.
883
+ # Expected values are of the form:
884
+ # `projects/<project_id>/instances/<instance_id>/databases/<database_id>/sessions/<session_id>`.
885
+ # If nil is specified nothing will be sent.
886
+ # @param call_options [::Hash, nil] Optional. A hash of values to specify the custom
887
+ # call options. Example option `:timeout`.
888
+ # @param route_to_leader [::String, nil] Optional. The value to be sent
889
+ # as `x-goog-spanner-route-to-leader` header for leader aware routing.
890
+ # Expected values: `"true"` or `"false"`. If nil is specified nothing will be sent.
891
+ # @private
892
+ # @return [::Gapic::CallOptions]
832
893
  def default_options session_name: nil, call_options: nil, route_to_leader: nil
833
894
  opts = {}
834
895
  metadata = {}
@@ -44,8 +44,8 @@ module Google
44
44
  #
45
45
  class Session
46
46
  # The wrapped `V1::Session` protobuf session object.
47
- # @return [::Google::Cloud::Spanner::V1::Session]
48
47
  # @private
48
+ # @return [::Google::Cloud::Spanner::V1::Session]
49
49
  attr_accessor :grpc
50
50
 
51
51
  # The `Spanner::Service` object.
@@ -59,7 +59,7 @@ module Google
59
59
  # @return [::Hash, nil]
60
60
  attr_accessor :query_options
61
61
 
62
- # Creates a new Session instance.
62
+ # Creates a new `Spanner::Session` instance.
63
63
  # @param grpc [::Google::Cloud::Spanner::V1::Session] Underlying `V1::Session` object.
64
64
  # @param service [::Google::Cloud::Spanner::Service] A `Spanner::Service` object.
65
65
  # @param query_options [::Hash, nil] Optional. A hash of values to specify the custom
@@ -69,6 +69,7 @@ module Google
69
69
  @grpc = grpc
70
70
  @service = service
71
71
  @query_options = query_options
72
+ @created_time = Process.clock_gettime Process::CLOCK_MONOTONIC
72
73
  end
73
74
 
74
75
  # The unique identifier for the project.
@@ -216,6 +217,9 @@ module Google
216
217
  # * `:retry_codes` (`Array<String>`) - The error codes that should
217
218
  # trigger a retry.
218
219
  #
220
+ # @param precommit_token_notify [::Proc, nil] Optional.
221
+ # The notification function for the precommit token.
222
+ #
219
223
  # @return [Google::Cloud::Spanner::Results] The results of the query
220
224
  # execution.
221
225
  #
@@ -357,7 +361,8 @@ module Google
357
361
  def execute_query sql, params: nil, types: nil, transaction: nil,
358
362
  partition_token: nil, seqno: nil, query_options: nil,
359
363
  request_options: nil, call_options: nil, data_boost_enabled: nil,
360
- directed_read_options: nil, route_to_leader: nil
364
+ directed_read_options: nil, route_to_leader: nil,
365
+ precommit_token_notify: nil
361
366
  ensure_service!
362
367
  query_options = merge_if_present query_options, @query_options
363
368
 
@@ -373,7 +378,8 @@ module Google
373
378
 
374
379
  response = service.execute_streaming_sql path, sql, **execute_query_options
375
380
 
376
- results = Results.from_execute_query_response response, service, path, sql, execute_query_options
381
+ results = Results.from_execute_query_response response, service, path, sql, execute_query_options,
382
+ precommit_token_notify: precommit_token_notify
377
383
  @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
378
384
  results
379
385
  end
@@ -428,8 +434,8 @@ module Google
428
434
  # number of rows that were modified for each successful statement
429
435
  # before the error.
430
436
  #
431
- # @return [Array<Integer>] A list with the exact number of rows that
432
- # were modified for each DML statement.
437
+ # @return [::Google::Cloud::Spanner::V1::ExecuteBatchDmlResponse]
438
+ # An unwrapped result of the service call -- a `V1::ExecuteBatchDmlResponse` object.
433
439
  #
434
440
  def batch_update transaction, seqno, request_options: nil,
435
441
  call_options: nil
@@ -506,6 +512,9 @@ module Google
506
512
  # To see the available options refer to
507
513
  # ['Google::Cloud::Spanner::V1::ReadRequest::LockHint'](https://cloud.google.com/ruby/docs/reference/google-cloud-spanner-v1/latest/Google-Cloud-Spanner-V1-ReadRequest-LockHint)
508
514
  #
515
+ # @param precommit_token_notify [::Proc, nil] Optional.
516
+ # The notification function for the precommit token.
517
+ #
509
518
  # @return [Google::Cloud::Spanner::Results] The results of the read
510
519
  # operation.
511
520
  #
@@ -525,7 +534,7 @@ module Google
525
534
  def read table, columns, keys: nil, index: nil, limit: nil,
526
535
  transaction: nil, partition_token: nil, request_options: nil,
527
536
  call_options: nil, data_boost_enabled: nil, directed_read_options: nil,
528
- route_to_leader: nil, order_by: nil, lock_hint: nil
537
+ route_to_leader: nil, order_by: nil, lock_hint: nil, precommit_token_notify: nil
529
538
  ensure_service!
530
539
 
531
540
  read_options = {
@@ -544,7 +553,8 @@ module Google
544
553
  response = service.streaming_read_table \
545
554
  path, table, columns, **read_options
546
555
 
547
- results = Results.from_read_response response, service, path, table, columns, read_options
556
+ results = Results.from_read_response response, service, path, table, columns, read_options,
557
+ precommit_token_notify: precommit_token_notify
548
558
 
549
559
  @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
550
560
 
@@ -675,12 +685,24 @@ module Google
675
685
  ensure_service!
676
686
  commit = Commit.new
677
687
  yield commit
678
- commit_resp = service.commit path, commit.mutations,
679
- transaction_id: transaction_id,
680
- exclude_txn_from_change_streams: exclude_txn_from_change_streams,
681
- commit_options: commit_options,
682
- request_options: request_options,
683
- call_options: call_options
688
+
689
+ should_retry = true
690
+ # @type [Google::Cloud::Spanner::V1::MultiplexedSessionPrecommitToken]
691
+ precommit_token = nil
692
+ while should_retry
693
+ commit_resp = service.commit(path,
694
+ commit.mutations,
695
+ transaction_id: transaction_id,
696
+ exclude_txn_from_change_streams: exclude_txn_from_change_streams,
697
+ commit_options: commit_options,
698
+ request_options: request_options,
699
+ call_options: call_options,
700
+ precommit_token: precommit_token)
701
+
702
+ precommit_token = commit_resp.precommit_token
703
+ should_retry = !precommit_token.nil?
704
+ end
705
+
684
706
  @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
685
707
  resp = CommitResponse.from_grpc commit_resp
686
708
  commit_options ? resp : resp.timestamp
@@ -1369,9 +1391,15 @@ module Google
1369
1391
  true
1370
1392
  end
1371
1393
 
1372
- ##
1394
+ # Explicitly begins a new transaction and creates a server-side transaction object.
1395
+ # Unlike {#create_empty_transaction}, this method makes an immediate
1396
+ # `BeginTransaction` RPC call.
1397
+ #
1398
+ # @param exclude_txn_from_change_streams [::Boolean] Optional. Defaults to `false`.
1399
+ # When `exclude_txn_from_change_streams` is set to `true`, it prevents read
1400
+ # or write transactions from being tracked in change streams.
1373
1401
  # @private
1374
- # Creates a new transaction object every time.
1402
+ # @return [::Google::Cloud::Spanner::Transaction]
1375
1403
  def create_transaction exclude_txn_from_change_streams: false
1376
1404
  route_to_leader = LARHeaders.begin_transaction true
1377
1405
  tx_grpc = service.begin_transaction path,
@@ -1380,37 +1408,34 @@ module Google
1380
1408
  Transaction.from_grpc tx_grpc, self, exclude_txn_from_change_streams: exclude_txn_from_change_streams
1381
1409
  end
1382
1410
 
1383
- ##
1411
+ # Creates a new empty transaction wrapper without a server-side object.
1412
+ # This is used for inline-begin transactions and does not make an RPC call.
1413
+ # See {#create_transaction} for the RPC-based method.
1414
+ #
1415
+ # @param exclude_txn_from_change_streams [::Boolean] Optional. Defaults to `false`.
1416
+ # When `exclude_txn_from_change_streams` is set to `true`, it prevents read
1417
+ # or write transactions from being tracked in change streams.
1418
+ # @param previous_transaction_id [::String, nil] Optional.
1419
+ # An id of the previous transaction, if this new transaction wrapper is being created
1420
+ # as a part of a retry. Previous transaction id should be added to TransactionOptions
1421
+ # of a new ReadWrite transaction when retry is attempted.
1384
1422
  # @private
1385
- # Creates a new transaction object without the grpc object
1386
- # within it. Use it for inline-begin of a transaction.
1387
- def create_empty_transaction exclude_txn_from_change_streams: false
1388
- Transaction.from_grpc nil, self, exclude_txn_from_change_streams: exclude_txn_from_change_streams
1389
- end
1390
-
1391
- ##
1392
- # Reloads the session resource. Useful for determining if the session is
1393
- # still valid on the Spanner API.
1394
- def reload!
1395
- ensure_service!
1396
- @grpc = service.get_session path
1397
- @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
1398
- self
1399
- rescue Google::Cloud::NotFoundError
1400
- labels = @grpc.labels.to_h unless @grpc.labels.to_h.empty?
1401
- @grpc = service.create_session \
1402
- V1::Spanner::Paths.database_path(
1403
- project: project_id, instance: instance_id, database: database_id
1404
- ),
1405
- labels: labels
1406
- @last_updated_at = Process.clock_gettime Process::CLOCK_MONOTONIC
1407
- self
1423
+ # @return [::Google::Cloud::Spanner::Transaction] The new *empty-wrapper* transaction object.
1424
+ def create_empty_transaction exclude_txn_from_change_streams: false, previous_transaction_id: nil
1425
+ Transaction.from_grpc nil, self, exclude_txn_from_change_streams: exclude_txn_from_change_streams,
1426
+ previous_transaction_id: previous_transaction_id
1408
1427
  end
1409
1428
 
1410
- ##
1429
+ # If the session is non-multiplexed, keeps the session alive by executing `"SELECT 1"`.
1430
+ # This method will re-create the session if necessary.
1431
+ # For multiplexed session the keepalive is not required and this method immediately returns `true`.
1411
1432
  # @private
1412
- # Keeps the session alive by executing `"SELECT 1"`.
1433
+ # @return [::Boolean]
1434
+ # `true` if the session is multiplexed or if the keepalive was successful for non-multiplexed session,
1435
+ # `false` if the non-multiplexed session was not found and the had to be recreated.
1413
1436
  def keepalive!
1437
+ return true if multiplexed?
1438
+
1414
1439
  ensure_service!
1415
1440
  route_to_leader = LARHeaders.execute_query false
1416
1441
  execute_query "SELECT 1", route_to_leader: route_to_leader
@@ -1425,15 +1450,19 @@ module Google
1425
1450
  false
1426
1451
  end
1427
1452
 
1428
- ##
1429
- # Permanently deletes the session.
1453
+ # Permanently deletes the session unless this session is multiplexed.
1454
+ # Multiplexed sessions can not be deleted, and this method immediately returns.
1455
+ # @private
1456
+ # @return [void]
1430
1457
  def release!
1458
+ return if multiplexed?
1431
1459
  ensure_service!
1432
1460
  service.delete_session path
1433
1461
  end
1434
1462
 
1435
1463
  # Determines if the session has been idle longer than the given
1436
- # duration.
1464
+ # duration in seconds.
1465
+ #
1437
1466
  # @param duration_sec [::Numeric] interval in seconds
1438
1467
  # @private
1439
1468
  # @return [::Boolean]
@@ -1442,7 +1471,17 @@ module Google
1442
1471
  Process.clock_gettime(Process::CLOCK_MONOTONIC) > @last_updated_at + duration_sec
1443
1472
  end
1444
1473
 
1445
- # Creates a new Session instance from a `V1::Session`.
1474
+ # Determines if the session did exist for at least the given
1475
+ # duration in seconds.
1476
+ #
1477
+ # @param duration_sec [::Numeric] interval in seconds
1478
+ # @private
1479
+ # @return [::Boolean]
1480
+ def existed_since? duration_sec
1481
+ Process.clock_gettime(Process::CLOCK_MONOTONIC) > @created_time + duration_sec
1482
+ end
1483
+
1484
+ # Creates a new `Spanner::Session` instance from a `V1::Session` object.
1446
1485
  # @param grpc [::Google::Cloud::Spanner::V1::Session] Underlying `V1::Session` object.
1447
1486
  # @param service [::Google::Cloud::Spanner::Service] A `Spanner::Service` ref.
1448
1487
  # @param query_options [::Hash, nil] Optional. A hash of values to specify the custom
@@ -1461,6 +1500,13 @@ module Google
1461
1500
 
1462
1501
  protected
1463
1502
 
1503
+ # Whether this session is multiplexed.
1504
+ # @private
1505
+ # @return [::Boolean]
1506
+ def multiplexed?
1507
+ @grpc.multiplexed
1508
+ end
1509
+
1464
1510
  ##
1465
1511
  # @private Raise an error unless an active connection to the service is
1466
1512
  # available.