Varenik

Рейтинг
85
Регистрация
10.01.2012
просто как мне кажется, по коду, у вас там вторая таблица это какая то таблица уведомлений

Верно. В нее просто идет запись "истории" присвоения ord.id. Но конечная цель - отдать пользователю этот ID.

Aisamiery:
по вашему коду не очень понятно если честно. Почему бы вам не обрабатывать это в единый поток, например скриптом консоли? или вам нужен ответ пользователю?

Мало того что нужен ответ пользователю, так еще и на приеме есть данные, на основе которых идут выборки.

Нет дельных мыслей обхода моей рукожопости?

другой сервер, где нет панельки

Если правильно понял, то обратно какой-то VPS без панели управления. А не пробовали через консоль подключится под этим пользователем?

Aisamiery:
Для начала опишите задачу по конкретнее которую вы решаете, мы попробуем подсказать более элегантное решение в вашем случае

Вот собственно код (не весь - внутри есть еще обработчики). Частично задача решилась, но Немного баги встречаются в других выборках, связанных с таблицей

$dbase->query("BEGIN");
// начало выборки
$new_order = $dbase->super_query("SELECT o.* FROM ord o
INNER JOIN status_ord so ON so.id = o.id_status_ord
INNER JOIN status s ON s.id = so.id_status
WHERE so.id_status = 1 AND o.is_user = 0 AND o.comment!='' ORDER BY o.id ASC FOR UPDATE");
if (!$new_order) {
$new_order = $dbase->super_query("SELECT o.* FROM ord o
INNER JOIN status_ord so ON so.id = o.id_status_ord
INNER JOIN status s ON s.id = so.id_status
INNER JOIN orders_sets os ON o.id=os.order_id
WHERE so.id_status = 1 AND o.is_user = 0 ORDER BY o.id ASC FOR UPDATE");
}

/* Тут еще ряд выборок, которые и выполняются 0.5 секунды */

if ($new_order) {
$issue_informer = $dbase->super_query("SELECT * FROM messages WHERE recipient_id = ". $recipient_id ." AND type='new_order' AND parent_id='". $new_order***91;'id'] ."'");

if(!$issue_informer) {
$dbase->query("UPDATE ord SET is_user = ". $recipient_id ." WHERE id=". $new_order['id'] ."");

// По факту финиш обработки. Именно от начала до этого момента другой пользователь может успеть "выхватить" этот же $new_order['id']
$dbase->query("INSERT INTO messages(parent_id, type, sender_id, recipient_id, message, create_at, expired_at, status) VALUES (". $new_order['id'] .", 'new_order', 225, ". $recipient_id .", '', now(), now(), 0)");
}

}

$tmp = $dbase->query("COMMIT");

Буду признателен за дельный совет

Dreammaker:
Aisamiery, я тоже хотел написать, что здесь, mutex или что-то подобное должно быть, но все так уверенно начали советовать транзакции, что я начал верить в этом сам :)

И по-хорошему, нужно бы дополнительную информацию от ТС, что должен получить второй пользователь, который полез "невовремя". В первом посте об этом не говорится, а тут могут быть нюансы.

Второй также должен получить table_1.id, только отличительный от того что уже выбран у первого пользователя.

Сама выборка сложная с многочисленными JOIN

Спасибо. Понял куда рыть для моей задачи нужно - Блокировка уровня строки🍿

Sly32:
транзакции использовать

Можно простой пример? Читал о блокировках и транзакция MySQL, но если прямо - не особо понимаю что и к чему.

И блокировка происходит таблицы в целом или только конкретной записи? Что получает в ответ другой запрос, когда пытается считать эту строку?

По идее, при наличии индекса по uid быстрее может оказаться вложенный запрос вроде такого:

Спасибо. Навело на мысли... Буду пробовать

Всего: 223