From 1ab570c97f6124ec4249f03c58cbb586f147e11f Mon Sep 17 00:00:00 2001 From: Tom Clegg Date: Sun, 7 Dec 2014 03:06:04 -0500 Subject: [PATCH] 4533: Wait up to 10s for "lock tables". refs #4533 --- .../app/controllers/database_controller.rb | 55 +++++++++++-------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/services/api/app/controllers/database_controller.rb b/services/api/app/controllers/database_controller.rb index 1e577ae54f..04c0e79d6c 100644 --- a/services/api/app/controllers/database_controller.rb +++ b/services/api/app/controllers/database_controller.rb @@ -29,31 +29,42 @@ class DatabaseController < ApplicationController fixturesets = Dir.glob(Rails.root.join('test', 'fixtures', '*.yml')). collect { |yml| yml.match(/([^\/]*)\.yml$/)[1] } - ActiveRecord::Base.transaction do - # Avoid deadlock by locking all tables before doing anything - # drastic. - table_names = '"' + ActiveRecord::Base.connection.tables.join('","') + '"' - ActiveRecord::Base.connection.execute \ - "LOCK TABLE #{table_names} IN ACCESS EXCLUSIVE MODE" - - # Delete existing fixtures (and everything else) from fixture - # tables - fixturesets.each do |x| - x.classify.constantize.unscoped.delete_all - end + table_names = '"' + ActiveRecord::Base.connection.tables.join('","') + '"' + + attempts_left = 20 + begin + ActiveRecord::Base.transaction do + # Avoid deadlock by locking all tables before doing anything + # drastic. + ActiveRecord::Base.connection.execute \ + "LOCK TABLE #{table_names} IN ACCESS EXCLUSIVE MODE" + + # Delete existing fixtures (and everything else) from fixture + # tables + fixturesets.each do |x| + x.classify.constantize.unscoped.delete_all + end - # create_fixtures() is a no-op for cached fixture sets, so - # uncache them all. - ActiveRecord::Fixtures.reset_cache - ActiveRecord::Fixtures. - create_fixtures(Rails.root.join('test', 'fixtures'), fixturesets) + # create_fixtures() is a no-op for cached fixture sets, so + # uncache them all. + ActiveRecord::Fixtures.reset_cache + ActiveRecord::Fixtures. + create_fixtures(Rails.root.join('test', 'fixtures'), fixturesets) - # Dump cache of permissions etc. - Rails.cache.clear - ActiveRecord::Base.connection.clear_query_cache + # Dump cache of permissions etc. + Rails.cache.clear + ActiveRecord::Base.connection.clear_query_cache - # Reload database seeds - DatabaseSeeds.install + # Reload database seeds + DatabaseSeeds.install + end + rescue ActiveRecord::StatementInvalid => e + if "#{e.inspect}" =~ /deadlock detected/i and (attempts_left -= 1) > 0 + logger.info "Waiting for lock -- #{e.inspect}" + sleep 0.5 + retry + end + raise end # Done. -- 2.30.2