Module: ActiveRecord::ConnectionAdapters::DatabaseStatements

Defined in:
lib/transaction_isolation_level/adapter_patches.rb

Constant Summary collapse

ORDER_OF_TRANSACTION_ISOLATION_LEVELS =
[:read_uncommitted, :read_committed, :repeatable_read, :serializable]

Instance Method Summary collapse

Instance Method Details

#transaction_isolation_level_from_sql(value) ⇒ Object



17
18
19
20
21
22
23
24
25
# File 'lib/transaction_isolation_level/adapter_patches.rb', line 17

def transaction_isolation_level_from_sql(value)
  case value.gsub('-', ' ').upcase
  when 'READ UNCOMMITTED' then :read_uncommitted
  when 'READ COMMITTED'   then :read_committed
  when 'REPEATABLE READ'  then :repeatable_read
  when 'SERIALIZABLE'     then :serializable
  else raise "Unknown transaction isolation level: #{value.inspect}"
  end
end

#transaction_isolation_level_sql(value) ⇒ Object



6
7
8
9
10
11
12
13
14
15
# File 'lib/transaction_isolation_level/adapter_patches.rb', line 6

def transaction_isolation_level_sql(value)
  case value
  when :read_uncommitted then 'ISOLATION LEVEL READ UNCOMMITTED'
  when :read_committed   then 'ISOLATION LEVEL READ COMMITTED'
  when :repeatable_read  then 'ISOLATION LEVEL REPEATABLE READ'
  when :serializable     then 'ISOLATION LEVEL SERIALIZABLE'
  when nil               then nil
  else raise "Unknown transaction isolation level: #{value.inspect}"
  end
end

#transaction_with_isolation_level(**options) ⇒ Object Also known as: transaction

Raises:

  • (ArgumentError)


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/transaction_isolation_level/adapter_patches.rb', line 27

def transaction_with_isolation_level(**options)
  isolation_level = options.delete(:isolation_level)
  minimum_isolation_level = options.delete(:minimum_isolation_level)

  raise ArgumentError,         "#{isolation_level.inspect} is not a known transaction isolation level" unless         isolation_level.nil? || ORDER_OF_TRANSACTION_ISOLATION_LEVELS.include?(isolation_level)
  raise ArgumentError, "#{minimum_isolation_level.inspect} is not a known transaction isolation level" unless minimum_isolation_level.nil? || ORDER_OF_TRANSACTION_ISOLATION_LEVELS.include?(minimum_isolation_level)

  if open_transactions == 0
    @transaction_isolation_level = isolation_level || minimum_isolation_level
  elsif isolation_level && isolation_level != (@transaction_isolation_level || default_transaction_isolation_level)
    raise IncompatibleTransactionIsolationLevel, "Asked to use transaction isolation level #{isolation_level}, but the transaction has already begun with isolation level #{@transaction_isolation_level || default_transaction_isolation_level}"
  end
  if minimum_isolation_level && ORDER_OF_TRANSACTION_ISOLATION_LEVELS.index(minimum_isolation_level) > ORDER_OF_TRANSACTION_ISOLATION_LEVELS.index(@transaction_isolation_level || default_transaction_isolation_level)
    raise IncompatibleTransactionIsolationLevel, "Asked to use transaction isolation level at least #{minimum_isolation_level}, but the transaction has already begun with isolation level #{@transaction_isolation_level || default_transaction_isolation_level}"
  end

  transaction_without_isolation_level(**options) { yield }
end