diff --git a/lib/active_record/connection_adapters/sqlserver/transaction.rb b/lib/active_record/connection_adapters/sqlserver/transaction.rb index 81a58e968..3d5052ab0 100644 --- a/lib/active_record/connection_adapters/sqlserver/transaction.rb +++ b/lib/active_record/connection_adapters/sqlserver/transaction.rb @@ -14,7 +14,15 @@ def sqlserver? def current_isolation_level return unless sqlserver? level = connection.user_options_isolation_level - level.blank? ? 'READ COMMITTED' : level.upcase + + # When READ_COMMITTED_SNAPSHOT is set to ON, + # user_options_isolation_level will be equal to 'read committed + # snapshot' which is not a valid isolation level + if level.blank? || level == 'read committed snapshot' + 'READ COMMITTED' + else + level.upcase + end end end diff --git a/test/cases/transaction_test_sqlserver.rb b/test/cases/transaction_test_sqlserver.rb index 6db739bfb..e16a63a53 100644 --- a/test/cases/transaction_test_sqlserver.rb +++ b/test/cases/transaction_test_sqlserver.rb @@ -52,6 +52,31 @@ class TransactionTestSQLServer < ActiveRecord::TestCase connection.user_options_isolation_level.must_match %r{read committed}i end + describe 'when READ_COMMITTED_SNAPSHOT is set' do + before do + connection.execute "ALTER DATABASE [#{connection.current_database}] SET ALLOW_SNAPSHOT_ISOLATION ON" + connection.execute "ALTER DATABASE [#{connection.current_database}] SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE" + end + + after do + connection.execute "ALTER DATABASE [#{connection.current_database}] SET ALLOW_SNAPSHOT_ISOLATION OFF" + connection.execute "ALTER DATABASE [#{connection.current_database}] SET READ_COMMITTED_SNAPSHOT OFF WITH ROLLBACK IMMEDIATE" + end + + it 'should use READ COMMITTED as an isolation level' do + connection.user_options_isolation_level.must_match "read committed snapshot" + + Ship.transaction(isolation: :serializable) do + Ship.create! name: 'Black Pearl' + end + + # We're actually testing that the isolation level was correctly reset to + # "READ COMMITTED", and that no exception was raised (it's reported back + # by SQL Server as "read committed snapshot"). + connection.user_options_isolation_level.must_match "read committed snapshot" + end + end + protected