transaction_isolation_continued 1.0.5 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.dockerignore +1 -0
- data/.github/workflows/main.yml +35 -20
- data/.github/workflows/rubygem.yml +28 -0
- data/.gitignore +3 -0
- data/{Gemfile.local → Gemfile.old.local} +9 -0
- data/README.md +77 -56
- data/docker/ruby-2.5/Dockerfile +6 -0
- data/docker/ruby-2.7/Dockerfile +6 -0
- data/docker/ruby-3.0/Dockerfile +6 -0
- data/docker/ruby-3.1/Dockerfile +6 -0
- data/docker/test-ruby-2.5.sh +26 -0
- data/docker/test-ruby-2.7.sh +29 -0
- data/docker/test-ruby-3.0.sh +26 -0
- data/docker/test-ruby-3.1.sh +26 -0
- data/docker/test-ruby.sh +8 -0
- data/docker-compose.yml +60 -0
- data/gemfiles/Gemfile.base +4 -0
- data/gemfiles/activerecord-5.2/Gemfile.sqlite3 +1 -1
- data/gemfiles/activerecord-6.0/Gemfile.sqlite3 +1 -1
- data/gemfiles/activerecord-6.1/Gemfile.sqlite3 +1 -1
- data/gemfiles/activerecord-7.0/Gemfile.sqlite3 +1 -1
- data/lib/transaction_isolation/active_record/base.rb +5 -3
- data/lib/transaction_isolation/active_record/connection_adapters/abstract_adapter.rb +10 -9
- data/lib/transaction_isolation/active_record/connection_adapters/mysql2_adapter.rb +29 -27
- data/lib/transaction_isolation/active_record/connection_adapters/postgresql_adapter.rb +26 -24
- data/lib/transaction_isolation/active_record/connection_adapters/sqlite3_adapter.rb +24 -21
- data/lib/transaction_isolation/active_record/errors.rb +2 -0
- data/lib/transaction_isolation/configuration.rb +6 -4
- data/lib/transaction_isolation/version.rb +3 -1
- data/lib/transaction_isolation.rb +16 -11
- data/lib/transaction_isolation_continued.rb +1 -0
- data/spec/gem_template_spec.rb +11 -0
- data/spec/spec_helper.rb +15 -0
- data/test/db/all.rb +2 -0
- data/test/db/db.rb +15 -15
- data/test/db/migrations.rb +6 -7
- data/test/db/queued_job.rb +2 -0
- data/test/integration/active_record/base/isolation_level_test.rb +3 -9
- data/test/integration/active_record/connection_adapters/any_adapter/current_isolation_level_test.rb +8 -16
- data/test/integration/active_record/connection_adapters/any_adapter/current_vendor_isolation_level_test.rb +8 -16
- data/test/integration/active_record/connection_adapters/any_adapter/isolation_level_test.rb +18 -29
- data/test/integration/active_record/connection_adapters/any_adapter/supports_isolation_levels_test.rb +2 -10
- data/test/integration/active_record/connection_adapters/any_adapter/translate_exception_test.rb +20 -26
- data/test/library_setup.rb +11 -9
- data/test/test_helper.rb +9 -6
- data/test/test_runner.rb +3 -2
- data/transaction_isolation_continued.gemspec +15 -15
- metadata +33 -20
- data/d +0 -1
- data/test/test_console.rb +0 -11
@@ -1,11 +1,12 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
if defined?(ActiveRecord::ConnectionAdapters::Mysql2Adapter)
|
2
4
|
|
3
5
|
module TransactionIsolation
|
4
6
|
module ActiveRecord
|
5
7
|
module ConnectionAdapters # :nodoc:
|
6
8
|
module Mysql2Adapter
|
7
|
-
|
8
|
-
def self.included( base )
|
9
|
+
def self.included(base)
|
9
10
|
base.class_eval do
|
10
11
|
alias_method :translate_exception_without_transaction_isolation_conflict, :translate_exception
|
11
12
|
alias_method :translate_exception, :translate_exception_with_transaction_isolation_conflict
|
@@ -17,18 +18,18 @@ if defined?( ActiveRecord::ConnectionAdapters::Mysql2Adapter )
|
|
17
18
|
end
|
18
19
|
|
19
20
|
VENDOR_ISOLATION_LEVEL = {
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
}
|
21
|
+
read_uncommitted: 'READ UNCOMMITTED',
|
22
|
+
read_committed: 'READ COMMITTED',
|
23
|
+
repeatable_read: 'REPEATABLE READ',
|
24
|
+
serializable: 'SERIALIZABLE'
|
25
|
+
}.freeze
|
25
26
|
|
26
27
|
ANSI_ISOLATION_LEVEL = {
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
}
|
28
|
+
'READ UNCOMMITTED' => :read_uncommitted,
|
29
|
+
'READ COMMITTED' => :read_committed,
|
30
|
+
'REPEATABLE READ' => :repeatable_read,
|
31
|
+
'SERIALIZABLE' => :serializable
|
32
|
+
}.freeze
|
32
33
|
|
33
34
|
def current_isolation_level
|
34
35
|
ANSI_ISOLATION_LEVEL[current_vendor_isolation_level]
|
@@ -37,28 +38,30 @@ if defined?( ActiveRecord::ConnectionAdapters::Mysql2Adapter )
|
|
37
38
|
# transaction_isolation was added in MySQL 5.7.20 as an alias for tx_isolation, which is now deprecated and is removed in MySQL 8.0. Applications should be adjusted to use transaction_isolation in preference to tx_isolation.
|
38
39
|
def current_vendor_isolation_level
|
39
40
|
isolation_variable = TransactionIsolation.config.mysql_isolation_variable
|
40
|
-
select_value(
|
41
|
+
select_value("SELECT @@session.#{isolation_variable}").gsub('-', ' ')
|
41
42
|
end
|
42
43
|
|
43
|
-
def isolation_level(
|
44
|
-
validate_isolation_level(
|
44
|
+
def isolation_level(level)
|
45
|
+
validate_isolation_level(level)
|
45
46
|
|
46
47
|
original_vendor_isolation_level = current_vendor_isolation_level if block_given?
|
47
48
|
|
48
|
-
execute(
|
49
|
+
execute("SET SESSION TRANSACTION ISOLATION LEVEL #{VENDOR_ISOLATION_LEVEL[level]}")
|
50
|
+
|
51
|
+
return unless block_given?
|
49
52
|
|
50
53
|
begin
|
51
54
|
yield
|
52
55
|
ensure
|
53
56
|
execute "SET SESSION TRANSACTION ISOLATION LEVEL #{original_vendor_isolation_level}"
|
54
|
-
end
|
57
|
+
end
|
55
58
|
end
|
56
59
|
|
57
60
|
def translate_exception_with_transaction_isolation_conflict(*args)
|
58
61
|
exception = args.first
|
59
62
|
|
60
|
-
if isolation_conflict?(
|
61
|
-
::ActiveRecord::TransactionIsolationConflict.new(
|
63
|
+
if isolation_conflict?(exception)
|
64
|
+
::ActiveRecord::TransactionIsolationConflict.new("Transaction isolation conflict detected: #{exception.message}")
|
62
65
|
else
|
63
66
|
translate_exception_without_transaction_isolation_conflict(*args)
|
64
67
|
end
|
@@ -66,18 +69,17 @@ if defined?( ActiveRecord::ConnectionAdapters::Mysql2Adapter )
|
|
66
69
|
|
67
70
|
ruby2_keywords :translate_exception_with_transaction_isolation_conflict if respond_to?(:ruby2_keywords, true)
|
68
71
|
|
69
|
-
def isolation_conflict?(
|
70
|
-
[
|
71
|
-
|
72
|
-
exception.message =~ /#{Regexp.escape(
|
72
|
+
def isolation_conflict?(exception)
|
73
|
+
['Deadlock found when trying to get lock',
|
74
|
+
'Lock wait timeout exceeded'].any? do |error_message|
|
75
|
+
exception.message =~ /#{Regexp.escape(error_message)}/i
|
73
76
|
end
|
74
77
|
end
|
75
|
-
|
76
78
|
end
|
77
79
|
end
|
78
80
|
end
|
79
81
|
end
|
80
82
|
|
81
|
-
ActiveRecord::ConnectionAdapters::Mysql2Adapter.
|
83
|
+
ActiveRecord::ConnectionAdapters::Mysql2Adapter.include TransactionIsolation::ActiveRecord::ConnectionAdapters::Mysql2Adapter
|
82
84
|
|
83
|
-
end
|
85
|
+
end
|
@@ -1,11 +1,12 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
|
2
4
|
|
3
5
|
module TransactionIsolation
|
4
6
|
module ActiveRecord
|
5
7
|
module ConnectionAdapters # :nodoc:
|
6
8
|
module PostgreSQLAdapter
|
7
|
-
|
8
|
-
def self.included( base )
|
9
|
+
def self.included(base)
|
9
10
|
base.class_eval do
|
10
11
|
alias_method :translate_exception_without_transaction_isolation_conflict, :translate_exception
|
11
12
|
alias_method :translate_exception, :translate_exception_with_transaction_isolation_conflict
|
@@ -17,39 +18,41 @@ if defined?( ActiveRecord::ConnectionAdapters::PostgreSQLAdapter )
|
|
17
18
|
end
|
18
19
|
|
19
20
|
VENDOR_ISOLATION_LEVEL = {
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
}
|
21
|
+
read_uncommitted: 'READ UNCOMMITTED',
|
22
|
+
read_committed: 'READ COMMITTED',
|
23
|
+
repeatable_read: 'REPEATABLE READ',
|
24
|
+
serializable: 'SERIALIZABLE'
|
25
|
+
}.freeze
|
25
26
|
|
26
27
|
ANSI_ISOLATION_LEVEL = {
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
}
|
28
|
+
'READ UNCOMMITTED' => :read_uncommitted,
|
29
|
+
'READ COMMITTED' => :read_committed,
|
30
|
+
'REPEATABLE READ' => :repeatable_read,
|
31
|
+
'SERIALIZABLE' => :serializable
|
32
|
+
}.freeze
|
32
33
|
|
33
34
|
def current_isolation_level
|
34
35
|
ANSI_ISOLATION_LEVEL[current_vendor_isolation_level]
|
35
36
|
end
|
36
37
|
|
37
38
|
def current_vendor_isolation_level
|
38
|
-
select_value(
|
39
|
+
select_value('SHOW TRANSACTION ISOLATION LEVEL').upcase
|
39
40
|
end
|
40
41
|
|
41
|
-
def isolation_level(
|
42
|
-
validate_isolation_level(
|
42
|
+
def isolation_level(level)
|
43
|
+
validate_isolation_level(level)
|
43
44
|
|
44
45
|
original_vendor_isolation_level = current_vendor_isolation_level if block_given?
|
45
46
|
|
46
47
|
execute "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL #{VENDOR_ISOLATION_LEVEL[level]}"
|
47
48
|
|
49
|
+
return unless block_given?
|
50
|
+
|
48
51
|
begin
|
49
52
|
yield
|
50
53
|
ensure
|
51
54
|
execute "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL #{original_vendor_isolation_level}"
|
52
|
-
end
|
55
|
+
end
|
53
56
|
end
|
54
57
|
|
55
58
|
def translate_exception_with_transaction_isolation_conflict(*args)
|
@@ -64,18 +67,17 @@ if defined?( ActiveRecord::ConnectionAdapters::PostgreSQLAdapter )
|
|
64
67
|
|
65
68
|
ruby2_keywords :translate_exception_with_transaction_isolation_conflict if respond_to?(:ruby2_keywords, true)
|
66
69
|
|
67
|
-
def isolation_conflict?(
|
68
|
-
[
|
69
|
-
|
70
|
-
exception.message =~ /#{Regexp.escape(
|
70
|
+
def isolation_conflict?(exception)
|
71
|
+
['deadlock detected',
|
72
|
+
'could not serialize access'].any? do |error_message|
|
73
|
+
exception.message =~ /#{Regexp.escape(error_message)}/i
|
71
74
|
end
|
72
75
|
end
|
73
|
-
|
74
76
|
end
|
75
77
|
end
|
76
78
|
end
|
77
79
|
end
|
78
80
|
|
79
|
-
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.
|
81
|
+
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.include TransactionIsolation::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
|
80
82
|
|
81
|
-
end
|
83
|
+
end
|
@@ -1,11 +1,12 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
if defined?(ActiveRecord::ConnectionAdapters::SQLite3Adapter)
|
2
4
|
|
3
5
|
module TransactionIsolation
|
4
6
|
module ActiveRecord
|
5
7
|
module ConnectionAdapters # :nodoc:
|
6
8
|
module SQLite3Adapter
|
7
|
-
|
8
|
-
def self.included( base )
|
9
|
+
def self.included(base)
|
9
10
|
base.class_eval do
|
10
11
|
alias_method :translate_exception_without_transaction_isolation_conflict, :translate_exception
|
11
12
|
alias_method :translate_exception, :translate_exception_with_transaction_isolation_conflict
|
@@ -17,37 +18,39 @@ if defined?( ActiveRecord::ConnectionAdapters::SQLite3Adapter )
|
|
17
18
|
end
|
18
19
|
|
19
20
|
VENDOR_ISOLATION_LEVEL = {
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
}
|
21
|
+
read_uncommitted: 'read_uncommitted = 1',
|
22
|
+
read_committed: 'read_uncommitted = 0',
|
23
|
+
repeatable_read: 'read_uncommitted = 0',
|
24
|
+
serializable: 'read_uncommitted = 0'
|
25
|
+
}.freeze
|
25
26
|
|
26
27
|
ANSI_ISOLATION_LEVEL = {
|
27
|
-
|
28
|
-
|
29
|
-
}
|
28
|
+
'read_uncommitted = 1' => :read_uncommitted,
|
29
|
+
'read_uncommitted = 0' => :serializable
|
30
|
+
}.freeze
|
30
31
|
|
31
32
|
def current_isolation_level
|
32
33
|
ANSI_ISOLATION_LEVEL[current_vendor_isolation_level]
|
33
34
|
end
|
34
35
|
|
35
36
|
def current_vendor_isolation_level
|
36
|
-
"read_uncommitted = #{select_value(
|
37
|
+
"read_uncommitted = #{select_value('PRAGMA read_uncommitted')}"
|
37
38
|
end
|
38
39
|
|
39
|
-
def isolation_level(
|
40
|
-
validate_isolation_level(
|
40
|
+
def isolation_level(level)
|
41
|
+
validate_isolation_level(level)
|
41
42
|
|
42
43
|
original_vendor_isolation_level = current_vendor_isolation_level if block_given?
|
43
44
|
|
44
45
|
execute "PRAGMA #{VENDOR_ISOLATION_LEVEL[level]}"
|
45
46
|
|
47
|
+
return unless block_given?
|
48
|
+
|
46
49
|
begin
|
47
50
|
yield
|
48
51
|
ensure
|
49
52
|
execute "PRAGMA #{original_vendor_isolation_level}"
|
50
|
-
end
|
53
|
+
end
|
51
54
|
end
|
52
55
|
|
53
56
|
def translate_exception_with_transaction_isolation_conflict(*args)
|
@@ -63,11 +66,11 @@ if defined?( ActiveRecord::ConnectionAdapters::SQLite3Adapter )
|
|
63
66
|
ruby2_keywords :translate_exception_with_transaction_isolation_conflict if respond_to?(:ruby2_keywords, true)
|
64
67
|
|
65
68
|
# http://www.sqlite.org/c3ref/c_abort.html
|
66
|
-
def isolation_conflict?(
|
67
|
-
[
|
68
|
-
|
69
|
-
|
70
|
-
exception.message =~ /#{Regexp.escape(
|
69
|
+
def isolation_conflict?(exception)
|
70
|
+
['The database file is locked',
|
71
|
+
'A table in the database is locked',
|
72
|
+
'Database lock protocol error'].any? do |error_message|
|
73
|
+
exception.message =~ /#{Regexp.escape(error_message)}/i
|
71
74
|
end
|
72
75
|
end
|
73
76
|
end
|
@@ -75,6 +78,6 @@ if defined?( ActiveRecord::ConnectionAdapters::SQLite3Adapter )
|
|
75
78
|
end
|
76
79
|
end
|
77
80
|
|
78
|
-
ActiveRecord::ConnectionAdapters::SQLite3Adapter.
|
81
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.include TransactionIsolation::ActiveRecord::ConnectionAdapters::SQLite3Adapter
|
79
82
|
|
80
83
|
end
|
@@ -1,16 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TransactionIsolation
|
2
4
|
class Configuration
|
3
|
-
attr_accessor :mysql_isolation_variable
|
4
|
-
attr_accessor :detect_mysql_isolation_variable
|
5
|
+
attr_accessor :mysql_isolation_variable, :detect_mysql_isolation_variable
|
5
6
|
|
6
7
|
def initialize
|
7
8
|
@mysql_isolation_variable = 'tx_isolation'
|
8
9
|
@detect_mysql_isolation_variable = true
|
9
10
|
end
|
10
11
|
|
11
|
-
def mysql_isolation_variable=(
|
12
|
+
def mysql_isolation_variable=(value)
|
12
13
|
unless value.in? %w[transaction_isolation tx_isolation]
|
13
|
-
raise ArgumentError,
|
14
|
+
raise ArgumentError,
|
15
|
+
"Invalid MySQL isolation variable '#{value}'. Supported variables include 'transaction_isolation' and 'tx_isolation'."
|
14
16
|
end
|
15
17
|
|
16
18
|
@mysql_isolation_variable = value
|
@@ -1,9 +1,10 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_record'
|
2
4
|
require_relative 'transaction_isolation/version'
|
3
5
|
require_relative 'transaction_isolation/configuration'
|
4
6
|
|
5
7
|
module TransactionIsolation
|
6
|
-
|
7
8
|
# Must be called after ActiveRecord established a connection.
|
8
9
|
# Only then we know which connection adapter is actually loaded and can be enhanced.
|
9
10
|
# Please note ActiveRecord does not load unused adapters.
|
@@ -31,21 +32,25 @@ module TransactionIsolation
|
|
31
32
|
config
|
32
33
|
end
|
33
34
|
|
34
|
-
if defined?(
|
35
|
+
if defined?(::Rails)
|
35
36
|
# Setup applying the patch after Rails is initialized.
|
36
37
|
class Railtie < ::Rails::Railtie
|
37
38
|
config.after_initialize do
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
TransactionIsolation.config.mysql_isolation_variable = '
|
42
|
-
|
43
|
-
|
39
|
+
begin
|
40
|
+
if TransactionIsolation.config.detect_mysql_isolation_variable && ActiveRecord::Base.connection.adapter_name == 'Mysql2'
|
41
|
+
mysql_version = ActiveRecord::Base.connection.select_value('SELECT version()')
|
42
|
+
TransactionIsolation.config.mysql_isolation_variable = if mysql_version >= '8'
|
43
|
+
'transaction_isolation'
|
44
|
+
else
|
45
|
+
'tx_isolation'
|
46
|
+
end
|
44
47
|
end
|
48
|
+
|
49
|
+
TransactionIsolation.apply_activerecord_patch
|
50
|
+
rescue ActiveRecord::NoDatabaseError
|
51
|
+
# This is expected when running rake db:create
|
45
52
|
end
|
46
|
-
TransactionIsolation.apply_activerecord_patch
|
47
53
|
end
|
48
54
|
end
|
49
55
|
end
|
50
|
-
|
51
56
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'transaction_isolation'
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "gem_template"
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
# Enable flags like --only-failures and --next-failure
|
7
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
8
|
+
|
9
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
10
|
+
config.disable_monkey_patching!
|
11
|
+
|
12
|
+
config.expect_with :rspec do |c|
|
13
|
+
c.syntax = :expect
|
14
|
+
end
|
15
|
+
end
|
data/test/db/all.rb
CHANGED
data/test/db/db.rb
CHANGED
@@ -1,37 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'fileutils'
|
2
4
|
|
3
5
|
module TransactionIsolation
|
4
6
|
module Test
|
5
7
|
module Db
|
6
|
-
|
7
8
|
def self.connect_to_mysql2
|
8
9
|
::ActiveRecord::Base.establish_connection(
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
10
|
+
adapter: 'mysql2',
|
11
|
+
database: ENV['MYSQL_DB_NAME'],
|
12
|
+
host: ENV['MYSQL_DB_HOST'],
|
13
|
+
user: 'root',
|
14
|
+
password: ENV['MYSQL_DB_PASS']
|
14
15
|
)
|
15
16
|
end
|
16
17
|
|
17
18
|
def self.connect_to_postgresql
|
18
19
|
::ActiveRecord::Base.establish_connection(
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
20
|
+
adapter: 'postgresql',
|
21
|
+
database: ENV['POSTGRESQL_DB_NAME'],
|
22
|
+
host: ENV['POSTGRESQL_DB_HOST'],
|
23
|
+
user: ENV['POSTGRESQL_DB_USER'],
|
24
|
+
password: ENV['POSTGRESQL_DB_PASS']
|
24
25
|
)
|
25
26
|
end
|
26
27
|
|
27
28
|
def self.connect_to_sqlite3
|
28
29
|
ActiveRecord::Base.establish_connection(
|
29
|
-
:
|
30
|
-
:
|
31
|
-
:
|
30
|
+
adapter: 'sqlite3',
|
31
|
+
database: ':memory:',
|
32
|
+
verbosity: 'silent'
|
32
33
|
)
|
33
34
|
end
|
34
|
-
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
data/test/db/migrations.rb
CHANGED
@@ -1,20 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TransactionIsolation
|
2
4
|
module Test
|
3
5
|
module Migrations
|
4
|
-
|
5
6
|
def self.run!
|
6
7
|
c = ::ActiveRecord::Base.connection
|
7
8
|
|
8
9
|
# Queued Jobs
|
9
|
-
|
10
|
-
c.create_table
|
11
|
-
t.text
|
12
|
-
t.integer
|
10
|
+
|
11
|
+
c.create_table 'queued_jobs', force: true do |t|
|
12
|
+
t.text 'job', null: false
|
13
|
+
t.integer 'status', default: 0, null: false
|
13
14
|
t.timestamps
|
14
15
|
end
|
15
|
-
|
16
16
|
end
|
17
|
-
|
18
17
|
end
|
19
18
|
end
|
20
19
|
end
|
data/test/db/queued_job.rb
CHANGED
@@ -1,23 +1,17 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
5
5
|
class ActiveRecordTest < Minitest::Test
|
6
|
-
|
7
6
|
class BaseTest < Minitest::Test
|
8
|
-
|
9
7
|
class IsolationLevelTest < Minitest::Test
|
10
|
-
|
11
8
|
def test_wraps_connection_isolation_level
|
12
|
-
ActiveRecord::Base.isolation_level(
|
9
|
+
ActiveRecord::Base.isolation_level(:serializable) do
|
13
10
|
ActiveRecord::Base.transaction do
|
14
|
-
assert_equal(
|
11
|
+
assert_equal(:serializable, ActiveRecord::Base.connection.current_isolation_level)
|
15
12
|
end
|
16
13
|
end
|
17
14
|
end
|
18
|
-
|
19
15
|
end
|
20
|
-
|
21
16
|
end
|
22
|
-
|
23
17
|
end
|
data/test/integration/active_record/connection_adapters/any_adapter/current_isolation_level_test.rb
CHANGED
@@ -1,33 +1,25 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
5
5
|
class ActiveRecordTest < Minitest::Test
|
6
|
-
|
7
6
|
class ConnectionAdaptersTest < Minitest::Test
|
8
|
-
|
9
7
|
class AnyAdapterTest < Minitest::Test
|
10
|
-
|
11
8
|
class CurrentIsolationLevelTest < Minitest::Test
|
12
|
-
|
13
9
|
def test_returns_correct_default_isolation_level
|
14
|
-
if defined?(
|
15
|
-
assert_equal(
|
10
|
+
if defined?(ActiveRecord::ConnectionAdapters::Mysql2Adapter)
|
11
|
+
assert_equal(:repeatable_read, ActiveRecord::Base.connection.current_isolation_level)
|
16
12
|
end
|
17
13
|
|
18
|
-
if defined?(
|
19
|
-
assert_equal(
|
14
|
+
if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
|
15
|
+
assert_equal(:read_committed, ActiveRecord::Base.connection.current_isolation_level)
|
20
16
|
end
|
21
17
|
|
22
|
-
|
23
|
-
assert_equal( :serializable, ActiveRecord::Base.connection.current_isolation_level )
|
24
|
-
end
|
25
|
-
end
|
18
|
+
return unless defined?(ActiveRecord::ConnectionAdapters::SQLite3Adapter)
|
26
19
|
|
20
|
+
assert_equal(:serializable, ActiveRecord::Base.connection.current_isolation_level)
|
21
|
+
end
|
27
22
|
end
|
28
|
-
|
29
23
|
end
|
30
|
-
|
31
24
|
end
|
32
|
-
|
33
25
|
end
|
@@ -1,33 +1,25 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
5
5
|
class ActiveRecordTest < Minitest::Test
|
6
|
-
|
7
6
|
class ConnectionAdaptersTest < Minitest::Test
|
8
|
-
|
9
7
|
class AnyAdapterTest < Minitest::Test
|
10
|
-
|
11
8
|
class CurrentVendorIsolationLevelTest < Minitest::Test
|
12
|
-
|
13
9
|
def test_returns_correct_default_vendor_isolation_level
|
14
|
-
if defined?(
|
15
|
-
assert_equal(
|
10
|
+
if defined?(ActiveRecord::ConnectionAdapters::Mysql2Adapter)
|
11
|
+
assert_equal('REPEATABLE READ', ActiveRecord::Base.connection.current_vendor_isolation_level)
|
16
12
|
end
|
17
13
|
|
18
|
-
if defined?(
|
19
|
-
assert_equal(
|
14
|
+
if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
|
15
|
+
assert_equal('READ COMMITTED', ActiveRecord::Base.connection.current_vendor_isolation_level)
|
20
16
|
end
|
21
17
|
|
22
|
-
|
23
|
-
assert_equal( 'read_uncommitted = 0', ActiveRecord::Base.connection.current_vendor_isolation_level )
|
24
|
-
end
|
25
|
-
end
|
18
|
+
return unless defined?(ActiveRecord::ConnectionAdapters::SQLite3Adapter)
|
26
19
|
|
20
|
+
assert_equal('read_uncommitted = 0', ActiveRecord::Base.connection.current_vendor_isolation_level)
|
21
|
+
end
|
27
22
|
end
|
28
|
-
|
29
23
|
end
|
30
|
-
|
31
24
|
end
|
32
|
-
|
33
25
|
end
|