Update deadlock_retry plugin with latest upstream code.
authorTom Hughes <tom@compton.nu>
Fri, 5 Jun 2009 23:07:10 +0000 (23:07 +0000)
committerTom Hughes <tom@compton.nu>
Fri, 5 Jun 2009 23:07:10 +0000 (23:07 +0000)
vendor/plugins/deadlock_retry/lib/deadlock_retry.rb
vendor/plugins/deadlock_retry/test/deadlock_retry_test.rb

index 413cb823c43ffd1e6c1c5deea73b1111447b15e1..39aeff869760e1963ff550c2f4e17bca5500cf9a 100644 (file)
@@ -44,6 +44,7 @@ module DeadlockRetry
       begin
         transaction_without_deadlock_handling(*objects, &block)
       rescue ActiveRecord::StatementInvalid => error
+        raise unless connection.open_transactions.zero?
         if DEADLOCK_ERROR_MESSAGES.any? { |msg| error.message =~ /#{Regexp.escape(msg)}/ }
           raise if retry_count >= MAXIMUM_RETRIES_ON_DEADLOCK
           retry_count += 1
index db0f6195d7ca2a9b7cc587152fab656e77c9d1e0..7124391f87d4335df9c71c70ad642f11744a9973 100644 (file)
@@ -20,8 +20,21 @@ require 'test/unit'
 require "#{File.dirname(__FILE__)}/../lib/deadlock_retry"
 
 class MockModel
-  def self.transaction(*objects, &block)
-    block.call
+  @@open_transactions = 0
+
+  def self.transaction(*objects)
+    @@open_transactions += 1
+    yield
+  ensure
+    @@open_transactions -= 1
+  end
+
+  def self.open_transactions
+    @@open_transactions
+  end
+
+  def self.connection
+    self
   end
 
   def self.logger
@@ -62,4 +75,21 @@ class DeadlockRetryTest < Test::Unit::TestCase
       MockModel.transaction { raise ActiveRecord::StatementInvalid, "Something else" }
     end
   end
+
+  def test_error_in_nested_transaction_should_retry_outermost_transaction
+    tries = 0
+    errors = 0
+
+    MockModel.transaction do
+      tries += 1
+      MockModel.transaction do
+        MockModel.transaction do
+          errors += 1
+          raise ActiveRecord::StatementInvalid, "MySQL::Error: Lock wait timeout exceeded" unless errors > 3
+        end
+      end
+    end
+  
+    assert_equal 4, tries
+  end
 end