Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Turn off deadlock_retry logging by default -- this was causing any de…

…adlocked transaction to fail silently and nastily
  • Loading branch information...
commit 84cd4acb7ee7ec11092e30943c2403b5296a7f13 1 parent b2f7dd2
Ben Osheroff and Simon Wistow authored osheroff committed
Showing with 39 additions and 4 deletions.
  1. +7 −2 lib/deadlock_retry.rb
  2. +32 −2 test/deadlock_retry_test.rb
View
9 lib/deadlock_retry.rb
@@ -20,6 +20,11 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
module DeadlockRetry
+ # Should we try to log innodb status -- if we don't have permission to,
+ # we actually break in-flight transactions, silently (!)
+ mattr_accessor :log_innodb_status
+ self.log_innodb_status = false
+
def self.included(base)
base.extend(ClassMethods)
base.class_eval do
@@ -48,7 +53,7 @@ def transaction_with_deadlock_handling(*objects, &block)
raise if retry_count >= MAXIMUM_RETRIES_ON_DEADLOCK
retry_count += 1
logger.info "Deadlock detected on retry #{retry_count}, restarting transaction"
- log_innodb_status
+ log_innodb_status if DeadlockRetry.log_innodb_status
retry
else
raise
@@ -80,4 +85,4 @@ def log_innodb_status
end
end
-ActiveRecord::Base.send(:include, DeadlockRetry)
+ActiveRecord::Base.send(:include, DeadlockRetry)
View
34 test/deadlock_retry_test.rb
@@ -1,7 +1,7 @@
require 'rubygems'
# Change the version if you want to test a different version of ActiveRecord
-gem 'activerecord', '2.2.2'
+gem 'activerecord', '2.3.8'
require 'active_record'
require 'active_record/version'
puts "Testing ActiveRecord #{ActiveRecord::VERSION::STRING}"
@@ -32,12 +32,29 @@ def self.logger
end
include DeadlockRetry
+
+ def self.log_innodb_status
+ @logged = true
+ end
+
+ def self.was_logged
+ @logged
+ end
+
+ def self.clear_was_logged
+ @logged = false
+ end
end
class DeadlockRetryTest < Test::Unit::TestCase
DEADLOCK_ERROR = "MySQL::Error: Deadlock found when trying to get lock"
TIMEOUT_ERROR = "MySQL::Error: Lock wait timeout exceeded"
+ def setup
+ DeadlockRetry.log_innodb_status = false
+ MockModel.clear_was_logged
+ end
+
def test_no_errors
assert_equal :success, MockModel.transaction { :success }
end
@@ -83,7 +100,20 @@ def test_error_in_nested_transaction_should_retry_outermost_transaction
end
end
end
-
+
assert_equal 4, tries
end
+
+ def test_should_not_log_innodb_by_default
+ errors = [ DEADLOCK_ERROR ] * 3
+ MockModel.transaction { raise ActiveRecord::StatementInvalid, errors.shift unless errors.empty?;}
+ assert !MockModel.was_logged
+ end
+
+ def test_should_log_if_logging_enabled
+ errors = [ DEADLOCK_ERROR ] * 3
+ DeadlockRetry.log_innodb_status = true
+ MockModel.transaction { raise ActiveRecord::StatementInvalid, errors.shift unless errors.empty?;}
+ assert MockModel.was_logged
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.