Skip to content
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

RUBY-1791 Raise if transactions not supported #2822

Merged
merged 4 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -538,6 +538,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 @@ -1185,5 +1187,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
Loading