Skip to content

Commit aaa2a56

Browse files
RUBY-1791 Raise if transactions not supported (mongodb#2822)
1 parent b7acff4 commit aaa2a56

File tree

5 files changed

+66
-0
lines changed

5 files changed

+66
-0
lines changed

Diff for: lib/mongo/error.rb

+1
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ def write_concern_error_labels
217217
require 'mongo/error/server_api_conflict'
218218
require 'mongo/error/server_api_not_supported'
219219
require 'mongo/error/server_not_usable'
220+
require 'mongo/error/transactions_not_supported'
220221
require 'mongo/error/unknown_payload_type'
221222
require 'mongo/error/unmet_dependency'
222223
require 'mongo/error/unsupported_option'

Diff for: lib/mongo/error/transactions_not_supported.rb

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# frozen_string_literal: true
2+
3+
# Copyright (C) 2019-2020 MongoDB Inc.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
module Mongo
18+
class Error
19+
# Transactions are not supported by the cluster. There might be the
20+
# following reasons:
21+
# - topology is standalone
22+
# - topology is replica set and server version is < 4.0
23+
# - topology is sharded and server version is < 4.2
24+
#
25+
# @param [ String ] reason The reason why transactions are no supported.
26+
#
27+
# @since 2.7.0
28+
class TransactionsNotSupported < Error
29+
def initialize(reason)
30+
super("Transactions are not supported for the cluster: #{reason}")
31+
end
32+
end
33+
end
34+
end

Diff for: lib/mongo/server/description/features.rb

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class Features
4848
# provided by the client during findAndModify operations, requiring the
4949
# driver to raise client-side errors when those options are provided.
5050
find_and_modify_option_validation: 8,
51+
sharded_transactions: 8,
5152
transactions: 7,
5253
scram_sha_256: 7,
5354
array_filters: 6,

Diff for: lib/mongo/session.rb

+15
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,8 @@ def with_transaction(options=nil)
555555
#
556556
# @since 2.6.0
557557
def start_transaction(options = nil)
558+
check_transactions_supported!
559+
558560
if options
559561
Lint.validate_read_concern_option(options[:read_concern])
560562

@@ -1202,5 +1204,18 @@ def check_matching_cluster!(client)
12021204
raise Mongo::Error::InvalidSession.new(MISMATCHED_CLUSTER_ERROR_MSG)
12031205
end
12041206
end
1207+
1208+
def check_transactions_supported!
1209+
raise Mongo::Error::TransactionsNotSupported, "standalone topology" if cluster.single?
1210+
1211+
cluster.next_primary.with_connection do |conn|
1212+
if cluster.replica_set? && !conn.features.transactions_enabled?
1213+
raise Mongo::Error::TransactionsNotSupported, "server version is < 4.0"
1214+
end
1215+
if cluster.sharded? && !conn.features.sharded_transactions_enabled?
1216+
raise Mongo::Error::TransactionsNotSupported, "sharded transactions require server version >= 4.2"
1217+
end
1218+
end
1219+
end
12051220
end
12061221
end

Diff for: spec/mongo/session_transaction_spec.rb

+15
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ class SessionTransactionSpecError < StandardError; end
2626
collection.delete_many
2727
end
2828

29+
describe 'start_transaction' do
30+
context 'when topology is sharded and server is < 4.2' do
31+
max_server_fcv '4.1'
32+
require_topology :sharded
33+
34+
it 'raises an error' do
35+
expect { session.start_transaction }.to raise_error(Mongo::Error::TransactionsNotSupported, /sharded transactions require server version/)
36+
end
37+
end
38+
end
39+
2940
describe '#abort_transaction' do
3041
require_topology :replica_set
3142

@@ -75,6 +86,8 @@ class SessionTransactionSpecError < StandardError; end
7586
end
7687

7788
describe '#with_transaction' do
89+
require_topology :replica_set
90+
7891
context 'callback successful' do
7992
it 'commits' do
8093
session.with_transaction do
@@ -123,6 +136,7 @@ class SessionTransactionSpecError < StandardError; end
123136
expect(Mongo::Utils).to receive(:monotonic_time).ordered.and_return(start + 1)
124137
expect(Mongo::Utils).to receive(:monotonic_time).ordered.and_return(start + 2)
125138
expect(Mongo::Utils).to receive(:monotonic_time).ordered.and_return(start + 200)
139+
allow(session).to receive('check_transactions_supported!').and_return true
126140

127141
expect do
128142
session.with_transaction do
@@ -156,6 +170,7 @@ class SessionTransactionSpecError < StandardError; end
156170
expect(Mongo::Utils).to receive(:monotonic_time).ordered.and_return(start + i)
157171
end
158172
expect(Mongo::Utils).to receive(:monotonic_time).ordered.and_return(start + 200)
173+
allow(session).to receive('check_transactions_supported!').and_return true
159174

160175
exc = Mongo::Error::OperationFailure.new('timeout test')
161176
exc.add_label(label)

0 commit comments

Comments
 (0)