Mysql2 :: Ошибка: превышено время ожидания блокировки; Попробуйте перезапустить транзакцию - PullRequest
0 голосов
/ 05 июля 2019
[ERROR] ActiveRecord::StatementInvalid, Mysql2::Error: Lock wait timeout exceeded; 
try restarting transaction: SELECT  `rpush_notifications`.`id` FROM `rpush_notifications` 
WHERE (processing = 0 AND delivered = 0 AND failed = 0 AND (deliver_after IS NULL OR deliver_after < '2019-07-03 14:27:05.462072'))  
ORDER BY deliver_after ASC, created_at ASC LIMIT 100 FOR UPDATE

Rpush gem версия 3.3.1

Моя конфигурация: config / initializers / rpush.rb

Rpush gem версия 3.3.1

Моя конфигурация: config / initializers / rpush.rb

Rpush.configure do |config|
config.client = :active_record
config.push_poll = 2
config.batch_size = 100
config.pid_file = 'tmp/pids/rpush.pid'
config.log_file = 'log/rpush.log'

config.log_level = (defined?(Rails) && Rails.logger) ? 
Rails.logger.level : ::Logger::Severity::INFO


end

Rpush.reflect do |on|


on.notification_delivered do |notification|
# notification.destroy
end

on.gcm_canonical_id do |old_id, canonical_id|
device = DeviceInfo.find_by_device_token(old_id)
device.device_token = canonical_id if device
device.save! if device
end

on.gcm_invalid_registration_id do |app, error, registration_id|
devices = DeviceInfo.where('device_token = ?', registration_id)
devices.each do |device|
if !device.uninstalled_flag
device.uninstalled_flag = true
device.uninstalled_at = Time.now
device.save
end
end
end
end


devices.androids.find_in_batches do |devices_batch|
tokens = devices_batch.map(&:device_token)
n = Rpush::Gcm::Notification.new
n.app = android_app
n.registration_ids = tokens
n.expiry = expiry
n.data = {'message' => @description, 'page' => @onclick_page, 'page_id' => 1, 'title' => @title, 'image_url' => @image_url}
n.priority = 'high'        # Optional, can be either 'normal' or 'high'
n.content_available = true
n.save!
end

1 Ответ

0 голосов
/ 08 июля 2019

Похоже, у вас есть конфликт транзакций между этим запросом и другим в соответствующих строках таблицы. В параллельной настройке SELECT ... FOR UPDATE плохая идея, так как транзакция будет выполняться дольше.

  • Проверьте изоляцию транзакции в БД и какой уровень требуется для правильной работы приложения.
  • Найдите другую транзакцию, которая удерживает блокировку при возникновении этой ошибки, и выясните, почему она слишком долго удерживает блокировку транзакции.
  • Проверьте, действительно ли необходима часть FOR UPDATE и можно ли изменить код, чтобы не использовать FOR UPDATE.
  • Может быть, вы можете добавить еще одну блокировку, либо в приложении, либо в БД для управления синхронизацией этих конкурирующих транзакций.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...