Skip to content

Commit

Permalink
RUBY-1791 Raise if transactions not supported (#2822)
Browse files Browse the repository at this point in the history
  • Loading branch information
comandeo-mongo authored Jan 15, 2024
1 parent 199816f commit 5f4a7e3
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/mongo/error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ def write_concern_error_labels
require 'mongo/error/server_api_conflict'
require 'mongo/error/server_api_not_supported'
require 'mongo/error/server_not_usable'
require 'mongo/error/transactions_not_supported'
require 'mongo/error/unknown_payload_type'
require 'mongo/error/unmet_dependency'
require 'mongo/error/unsupported_option'
Expand Down
34 changes: 34 additions & 0 deletions lib/mongo/error/transactions_not_supported.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# frozen_string_literal: true

# Copyright (C) 2019-2020 MongoDB Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

module Mongo
class Error
# Transactions are not supported by the cluster. There might be the
# following reasons:
# - topology is standalone
# - topology is replica set and server version is < 4.0
# - topology is sharded and server version is < 4.2
#
# @param [ String ] reason The reason why transactions are no supported.
#
# @since 2.7.0
class TransactionsNotSupported < Error
def initialize(reason)
super("Transactions are not supported for the cluster: #{reason}")
end
end
end
end
1 change: 1 addition & 0 deletions lib/mongo/server/description/features.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class Features
# provided by the client during findAndModify operations, requiring the
# driver to raise client-side errors when those options are provided.
find_and_modify_option_validation: 8,
sharded_transactions: 8,
transactions: 7,
scram_sha_256: 7,
array_filters: 6,
Expand Down
15 changes: 15 additions & 0 deletions lib/mongo/session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,8 @@ def with_transaction(options=nil)
#
# @since 2.6.0
def start_transaction(options = nil)
check_transactions_supported!

if options
Lint.validate_read_concern_option(options[:read_concern])

Expand Down Expand Up @@ -1202,5 +1204,18 @@ def check_matching_cluster!(client)
raise Mongo::Error::InvalidSession.new(MISMATCHED_CLUSTER_ERROR_MSG)
end
end

def check_transactions_supported!
raise Mongo::Error::TransactionsNotSupported, "standalone topology" if cluster.single?

cluster.next_primary.with_connection do |conn|
if cluster.replica_set? && !conn.features.transactions_enabled?
raise Mongo::Error::TransactionsNotSupported, "server version is < 4.0"
end
if cluster.sharded? && !conn.features.sharded_transactions_enabled?
raise Mongo::Error::TransactionsNotSupported, "sharded transactions require server version >= 4.2"
end
end
end
end
end
15 changes: 15 additions & 0 deletions spec/mongo/session_transaction_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ class SessionTransactionSpecError < StandardError; end
collection.delete_many
end

describe 'start_transaction' do
context 'when topology is sharded and server is < 4.2' do
max_server_fcv '4.1'
require_topology :sharded

it 'raises an error' do
expect { session.start_transaction }.to raise_error(Mongo::Error::TransactionsNotSupported, /sharded transactions require server version/)
end
end
end

describe '#abort_transaction' do
require_topology :replica_set

Expand Down Expand Up @@ -75,6 +86,8 @@ class SessionTransactionSpecError < StandardError; end
end

describe '#with_transaction' do
require_topology :replica_set

context 'callback successful' do
it 'commits' do
session.with_transaction do
Expand Down Expand Up @@ -123,6 +136,7 @@ class SessionTransactionSpecError < StandardError; end
expect(Mongo::Utils).to receive(:monotonic_time).ordered.and_return(start + 1)
expect(Mongo::Utils).to receive(:monotonic_time).ordered.and_return(start + 2)
expect(Mongo::Utils).to receive(:monotonic_time).ordered.and_return(start + 200)
allow(session).to receive('check_transactions_supported!').and_return true

expect do
session.with_transaction do
Expand Down Expand Up @@ -156,6 +170,7 @@ class SessionTransactionSpecError < StandardError; end
expect(Mongo::Utils).to receive(:monotonic_time).ordered.and_return(start + i)
end
expect(Mongo::Utils).to receive(:monotonic_time).ordered.and_return(start + 200)
allow(session).to receive('check_transactions_supported!').and_return true

exc = Mongo::Error::OperationFailure.new('timeout test')
exc.add_label(label)
Expand Down

0 comments on commit 5f4a7e3

Please sign in to comment.