2 require 'active_record'
4 if ENV['ACTIVERECORD_PATH'].nil?
6 Please set the ACTIVERECORD_PATH environment variable to the directory
7 containing the active_record.rb file.
10 $LOAD_PATH.unshift << ENV['ACTIVERECORD_PATH']
12 require 'active_record'
14 abort "ActiveRecord could not be found."
20 require "#{File.dirname(__FILE__)}/../lib/deadlock_retry"
23 @@open_transactions = 0
25 def self.transaction(*objects)
26 @@open_transactions += 1
29 @@open_transactions -= 1
32 def self.open_transactions
41 @logger ||= Logger.new(nil)
47 class DeadlockRetryTest < Test::Unit::TestCase
48 DEADLOCK_ERROR = "MySQL::Error: Deadlock found when trying to get lock"
49 TIMEOUT_ERROR = "MySQL::Error: Lock wait timeout exceeded"
52 assert_equal :success, MockModel.transaction { :success }
55 def test_no_errors_with_deadlock
56 errors = [ DEADLOCK_ERROR ] * 3
57 assert_equal :success, MockModel.transaction { raise ActiveRecord::StatementInvalid, errors.shift unless errors.empty?; :success }
61 def test_no_errors_with_lock_timeout
62 errors = [ TIMEOUT_ERROR ] * 3
63 assert_equal :success, MockModel.transaction { raise ActiveRecord::StatementInvalid, errors.shift unless errors.empty?; :success }
67 def test_error_if_limit_exceeded
68 assert_raise(ActiveRecord::StatementInvalid) do
69 MockModel.transaction { raise ActiveRecord::StatementInvalid, DEADLOCK_ERROR }
73 def test_error_if_unrecognized_error
74 assert_raise(ActiveRecord::StatementInvalid) do
75 MockModel.transaction { raise ActiveRecord::StatementInvalid, "Something else" }
79 def test_error_in_nested_transaction_should_retry_outermost_transaction
83 MockModel.transaction do
85 MockModel.transaction do
86 MockModel.transaction do
88 raise ActiveRecord::StatementInvalid, "MySQL::Error: Lock wait timeout exceeded" unless errors > 3