2014-10-30 3 views
0

Я все еще смущен о блокировке строки таблицы. Я использую MySQL/PHP, и вот мой сценарий.Блокировка уровня строки - MySQL - для обновления

У меня есть набор таблиц, которые мое приложение использует для отслеживания запросов и сообщений. Пользователь создает проводку (таблица POSTING (P)) для элемента (таблица ITEM (I)) и может отправлять запросы отдельным пользователям (таблица REQUEST (R)) или может публиковать их и получать ответные сообщения (таблица POSTING_RESPONSE (PR)), которые будут приниматься пользователем.

Пример: Я являюсь пользователем с велосипедом. Я отправляю его, а также отправляю запросы отдельным пользователям. Пользователи, которые получают запрос от меня, могут принимать/отклонять/или ничего не делать. Если они принимают - это зарезервировано. Другие пользователи могут найти мое сообщение и «подать заявку» на предмет. У меня есть возможность «принять» или «игнорировать» их запрос. Если я принимаю, элемент зарезервирован.

То, что я хочу делать, если кто-то принимает запрос:

  1. блокировки строки в пункте (I) таблица, соответствующая статья

  2. блокировки строки в POSTING (P) таблицы (если строка существует) соответствующий элементу

  3. блокировки строки (ы) в запросе таблицы (R), для любых запросов, отправляемых на пункт

  4. блокировки строки (ы) В POSTING_RESPONSE (PR) таблицы (если есть строки), соответствующий пункту

  5. обновления статуса ITEM в 'зарезервировано'

  6. обновление статуса POSTING к 'Недоступен'

  7. обновление все/любой POSTING_RESPONSE к «Отклонено»

  8. обновление всех ЗАПРОС на «Отклонено», кроме того, что принято - обновление, что один на «принято»

Игнорируйте избыточность статуса с помощью этого примера, пожалуйста.

Теперь я предположил, что # 1 - 4 можно сделать с помощью простого «select ... для обновления», оставив AUTOCOMMIT как false. Я мог бы избавиться от этих утверждений select, нужно ли мне обновлять или нет, и если да, я могу продолжить обновления. Затем, после завершения обновлений # 5-8, я бы зафиксировал и строки были бы разблокированы.

У меня проблемы с работой, и я не знаю, связано ли это с чем-то, что я делаю, или мое мышление неверно.

Еще одна вещь ... есть другие процессы, которые могут обновлять статус элемента, скажем, EXPIRED или CANCELED. Я надеюсь, что единственное решение моего подхода - не поставить все возможные условия в предложение WHERE в операторах UPDATE ... это не будет легко поддерживать.

+1

Обычно SELECT являются считанными, которые не являются блокирующими. Чтобы заблокировать SELECT, вы должны указать [блокировки чтения] (http://dev.mysql.com/doc/refman/5.6/en/innodb-locking-reads.html) –

+0

@JayBlanchard, можете ли вы объяснить? Может быть, я просто толстый, но я посмотрел на ваш рефери до и из того, что я собрал, есть только два варианта: LOCK IN SHARE MODE - который не будет препятствовать чтению - и FOR UPDATE - вот что показывает мой пример выше , FOR UPDATE не работает в моем примере выше? Если нет, что это должно быть? – NEW2WEB

+0

Нет, я просто пропустил это чтение. Что не работает для вас? –

ответ

0

Mini-transaction: сделайте это одним запросом.

UPDATE item 
LEFT JOIN posting 
    ON posting.item_id = item.id -- or however 
LEFT JOIN request 
    ON request.item_id = item.id -- or however 
LEFT JOIN posting_reponse 
    ON posting_response.item_id = item.id 
SET 
    item.status = 'Reserved', 
    posting.status = 'Unavailable', 
    posting_reponse.status = 'Rejected', 
    request.status = IF(request.id = some-current-id,'Accepted','Rejected') 
WHERE item.id = some-id AND item.status='Available'; 

...и прекратите задавать вопросы о блокировке для чтения, вы действительно не хотите, чтобы: P

+0

Wrikken - это, наверное, путь, но я все еще не понимаю, что не так с блокировкой для чтения? – NEW2WEB

+0

Если вы скажете: «никакой другой процесс не может читать эти данные», они не будут игнорировать эти данные, но процессы будут зависать, пока данные не станут доступными. Хотя это работает на очень низких проектах трафика, он не масштабируется за пределы нескольких посетителей: любой умеренно активный проект будет останавливаться на всех (суб) процессах/запросах, ожидающих других. Запросы занимают все больше времени по мере увеличения трафика, и вы достигаете точки, в которой происходят ошибки блокировки. Вы можете увеличить этот тайм-аут, но никто больше не будет использовать ваш проект, если им придется ждать> минуты, чтобы что-то произошло. – Wrikken