1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
# frozen_string_literal: true
require 'test_helper'
class TransactionScopingTest < GemTestCase
def supported?
%i[postgresql jdbcpostgresql].include?(env_db)
end
test 'raises an error when attempting to use transaction level locks if not supported' do
skip if supported?
Tag.transaction do
exception = assert_raises(ArgumentError) do
Tag.with_advisory_lock 'test', transaction: true do
raise 'should not get here'
end
end
assert_match(/#{Regexp.escape('not supported')}/, exception.message)
end
end
class PostgresqlTest < TransactionScopingTest
setup do
skip unless env_db == :postgresql
@pg_lock_count = lambda do
ApplicationRecord.connection.select_value("SELECT COUNT(*) FROM pg_locks WHERE locktype = 'advisory';").to_i
end
end
test 'session locks release after the block executes' do
Tag.transaction do
assert_equal(0, @pg_lock_count.call)
Tag.with_advisory_lock 'test' do
assert_equal(1, @pg_lock_count.call)
end
assert_equal(0, @pg_lock_count.call)
end
end
test 'session locks release when transaction fails inside block' do
Tag.transaction do
assert_equal(0, @pg_lock_count.call)
exception = assert_raises(ActiveRecord::StatementInvalid) do
Tag.with_advisory_lock 'test' do
Tag.connection.execute 'SELECT 1/0;'
end
end
assert_match(/#{Regexp.escape('division by zero')}/, exception.message)
assert_equal(0, @pg_lock_count.call)
end
end
test 'transaction level locks hold until the transaction completes' do
Tag.transaction do
assert_equal(0, @pg_lock_count.call)
Tag.with_advisory_lock 'test', transaction: true do
assert_equal(1, @pg_lock_count.call)
end
assert_equal(1, @pg_lock_count.call)
end
assert_equal(0, @pg_lock_count.call)
end
end
end
|