Как отключить запрос mysql ++ в C++

Я использую mysql ++, чтобы подключиться к базе данных MySQL для выполнения множества запросов к данным. Из-за того, что таблицы, из которых я читаю, постоянно записываются, и что мне нужно согласованное представление данных, я сначала блокирую таблицы. Однако MySQL не имеет понятия «NOWAIT» в своем запросе блокировки, поэтому, если таблицы заблокированы чем-то еще, что удерживает их заблокированными в течение длительного времени, мое приложение будет ждать. Я хочу, чтобы он мог вернуться и сказать что-то вроде «Невозможно получить блокировку» и повторить попытку через несколько секунд. Моя общая попытка в этот тайм-аут приведена ниже.

Если я запустил это после блокировки таблицы в базе данных, я получаю сообщение о том, что истекло время ожидания, но я не знаю, как затем завершить выполнение строки mysql_query. Буду признателен за любую помощь / идеи!


volatile sig_atomic_t success = 1;

void catch_alarm(int sig) {
        cout << "Timeout reached" << endl;
        success = 0;
        signal(sig,catch_alarm);
}

// connect to db etc.
// *SNIP

signal (SIGALRM, catch_alarm);
alarm(2);
mysql_query(p_connection,"LOCK TABLES XYZ as write");
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
1 581
7

Ответы 7

Вы можете выполнить блокирующий запрос в другом потоке и никогда не беспокоиться о тайм-ауте. Когда поступают некоторые данные, вы уведомляете поток, который должен знать о статусе транзакции.

Если бы я писал с нуля, я бы сделал это, но это серверное приложение, которое мы просто обновляем, а не переделываем.

вместо того, чтобы пытаться подделать транзакции с помощью блокировок таблиц, почему бы не переключиться на таблицы innodb, где вы получаете реальные транзакции? просто убедитесь, что уровень изоляции транзакции по умолчанию установлен на REPEATABLE READ.

Как я уже сказал, не так-то просто «переключить» или изменить архитектуру, когда это живая, в производственной системе. Я немного разочарован тем, что MySQL не предоставляет методов для проверки блокировок или отказа от ожидания блокировки.

Я не знаю, хорошая ли это идея с точки зрения использования ресурсов, «лучших практик», «чистоты» и всего остального ... но вы уже неоднократно описывали наручники, которые связывают вас, с точки зрения изменения архитектуры "чистая" система ... итак .....

Не могли бы вы открыть новое отдельное соединение только для отправки оператора LOCK? Затем закрыть это соединение, когда вы поймаете сигнал тайм-аута? При закрытии / разрушении соединения, которое было выделено для оператора LOCK, не будет ли это по существу "отменить" состояние LOCK? Я не уверен, произойдут ли такие события, как я описал / предположил, но, возможно, это то, что нужно проверить.

Мой опыт, описанный до сих пор, показывает мне, что закрытие соединения, в котором выполняется запрос, вызывает ошибку seg. Поэтому отправка этого запроса в другое соединение на самом деле не поможет, так как это также приведет к возникновению ошибки.

Вы можете реализовать поведение, подобное отмене, следующим образом:

Вы выполняете запрос в отдельном потоке, который продолжает выполняться независимо от того, истекло время ожидания или нет. Тайм-аут происходит в основном потоке и устанавливает для переменной значение «1», обозначающее, что это произошло. Затем вы делаете все, что хотите, в своем основном потоке.

Поток запроса после завершения запроса проверяет, не истек ли тайм-аут. Если этого не произошло, он сделает остальную работу, которую ему нужно сделать. Если БУДЕТ, он просто разблокирует только что заблокированные таблицы.

Я знаю, что это звучит немного расточительно, но период блокировки-разблокировки должен быть в основном мгновенным, и вы получите максимально приближенный к желаемому результату.

Другие вопросы по теме