lib/zena/db_helper/mysql.rb in zena-1.0.0.rc3 vs lib/zena/db_helper/mysql.rb in zena-1.0.0
- old
+ new
@@ -130,10 +130,14 @@
nil
end
end
end # date_condition
+ # Deadlock retry
+ DEADLOCK_REGEX = %r{Deadlock found when trying to get lock}
+ DEADLOCK_MAX_RETRY = 3
+
def prepare_connection
# Fixes timezone to "+0:0"
raise "prepare_connection executed too late, connection already active." if Class.new(ActiveRecord::Base).connected?
ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
@@ -143,10 +147,36 @@
execute("SET time_zone = '#{tz}'")
execute("SET collation_connection = 'utf8_unicode_ci'")
end
alias_method_chain :configure_connection, :zena
end
- end
+
+ class << ActiveRecord::Base
+ def transaction_with_deadlock_retry(*args, &block)
+ retry_count = 0
+
+ begin
+ transaction_without_deadlock_retry(*args, &block)
+ rescue ActiveRecord::StatementInvalid => error
+ # Raise if we are in a nested transaction
+ raise if connection.open_transactions != 0
+ if error.message =~ DEADLOCK_REGEX
+ retry_count += 1
+ if retry_count < DEADLOCK_MAX_RETRY
+ Node.logger.warn "#{Time.now.strftim('%Y-%m-%d %H:%M:%S')} [#{current_site.host}] Retry (#{retry_count}) #{error.message}"
+ retry
+ else
+ raise
+ end
+ else
+ # Not a deadlock error
+ raise
+ end
+ end
+ end
+ alias_method_chain :transaction, :deadlock_retry
+ end # class << ActiveRecord::Base
+ end # prepare_connection
end # class << self
end # Mysql
end # DbHelper
end # Zena
\ No newline at end of file