Skip to content

Commit e1955c3

Browse files
committed
Handle statements that cannot be retried on a new database connection by not reconnecting.
For example, retrying commit_db_transaction on a new connection would result in: The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.: COMMIT TRANSACTION
1 parent e10adcd commit e1955c3

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

lib/active_record/connection_adapters/sqlserver/database_statements.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,22 @@ def begin_db_transaction
5050
end
5151

5252
def commit_db_transaction
53-
do_execute "COMMIT TRANSACTION"
53+
disable_auto_reconnect { do_execute "COMMIT TRANSACTION" }
5454
end
5555

5656
def rollback_db_transaction
5757
do_execute "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION"
5858
end
5959

6060
def create_savepoint
61-
do_execute "SAVE TRANSACTION #{current_savepoint_name}"
61+
disable_auto_reconnect { do_execute "SAVE TRANSACTION #{current_savepoint_name}" }
6262
end
6363

6464
def release_savepoint
6565
end
6666

6767
def rollback_to_savepoint
68-
do_execute "ROLLBACK TRANSACTION #{current_savepoint_name}"
68+
disable_auto_reconnect { do_execute "ROLLBACK TRANSACTION #{current_savepoint_name}" }
6969
end
7070

7171
def add_limit_offset!(sql, options)

lib/active_record/connection_adapters/sqlserver_adapter.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,13 @@ def with_auto_reconnect
477477
end
478478
end
479479

480+
def disable_auto_reconnect
481+
old_auto_connect, self.class.auto_connect = self.class.auto_connect, false
482+
yield
483+
ensure
484+
self.class.auto_connect = old_auto_connect
485+
end
486+
480487
def auto_reconnected?
481488
return false unless auto_connect
482489
@auto_connecting = true

test/cases/connection_test_sqlserver.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,45 @@ def setup
115115
end
116116
end
117117

118+
context 'testing #disable_auto_reconnect' do
119+
should 'when auto reconnect setting is on' do
120+
with_auto_connect(true) do
121+
@connection.send(:disable_auto_reconnect) do
122+
assert !@connection.class.auto_connect
123+
end
124+
assert @connection.class.auto_connect
125+
end
126+
end
127+
128+
should 'when auto reconnect setting is off' do
129+
with_auto_connect(false) do
130+
@connection.send(:disable_auto_reconnect) do
131+
assert !@connection.class.auto_connect
132+
end
133+
assert !@connection.class.auto_connect
134+
end
135+
end
136+
end
137+
138+
should 'not auto reconnect on commit transaction' do
139+
@connection.disconnect!
140+
assert_raise(ActiveRecord::LostConnection) { @connection.commit_db_transaction }
141+
end
142+
143+
should 'gracefully ignore lost connections on rollback transaction' do
144+
@connection.disconnect!
145+
assert_nothing_raised { @connection.rollback_db_transaction }
146+
end
147+
148+
should 'not auto reconnect on create savepoint' do
149+
@connection.disconnect!
150+
assert_raise(ActiveRecord::LostConnection) { @connection.create_savepoint }
151+
end
152+
153+
should 'not auto reconnect on rollback to savepoint ' do
154+
@connection.disconnect!
155+
assert_raise(ActiveRecord::LostConnection) { @connection.rollback_to_savepoint }
156+
end
118157
end
119158

120159

0 commit comments

Comments
 (0)